Oracle by Alex
Home

 

Home

perf

la Pres.

technique

 

 
L'encapsulation des objets.
2.4.1. Le langage PL/SQL.
        Blocs
        Fonctions et procédures
        Paquetages
        Déclencheurs
        Programmes externes
2.4.2. Programmation des méthodes.
        Fonction MAP
        Fonction ORDER
2.4.3. Vues objet-relationnelles.

 

2.4.1. Le langage PL/SQL.

PL/SQL (Procedural Language / Structured Query Language) est utilisé par Oracle depuis sa version 6. Il permet de combiner des structures conditionnelles et répétitives avec les requêtes SQL dans un même programme.

Blocs

On peut regrouper un ensemble de requêtes SQL dans un bloc. Un bloc est envoyé entièrement du client vers le serveur. Ainsi on limite les accès au réseau. Les résultats intermédiaires sont traités sur le serveur et un seul résultat est renvoyé au client. Il est possible d'imbriquer les blocs.
Bilan : un flux client-serveur et un flux serveur-client sont nécessaires au traitement d'un ensemble de requêtes liées.

- Un bloc est composé de trois sections :
DECLARE      : déclaration des variables et curseurs
BEGIN            : le corps avec toutes les requêtes et instructions PL/SQL
EXCEPTION  : traitement des exceptions
On peut mettre le bloc dans un fichier fichier.sql et lancer son exécution par la commande start fichier.

En ce qui concerne les types, il était déjà possible de travailler avec des structures complexes de programme avec Oracle 7. Les records de la version 8 peuvent inclure des attributs de type ref - nested table - VARRAY et même des attributs de gestion de données multimédia !

- PL/SQL dispose des structures de contrôle suivantes :
la boucle pour (FOR condition LOOP ... END LOOP;)
la boucle répéter (LOOP ... EXIT WHEN condition END LOOP;)
la boucle tant que (WHILE (condition) LOOP ... END LOOP;)
la boucle curseur (FOR variable_curseur IN curseur LOOP ... END LOOP;)
Cette dernière structure de contrôle permet de parcourir facilement un ensemble de records qui constituent le résultat d'une requête. Les curseurs sont des variables spéciales qui permettent de traiter le résultat des requêtes. Ils sont particulièrement utiles lorsqu'on désire parcourir séquentiellement l'ensemble des résultats des requêtes.

- Les exceptions sont de trois types :
les exceptions internes à SQL prédéfinies par Oracle
les exceptions internes à SQL non prédéfinies par Oracle
les exceptions créées par l'utilisateur
AVANTAGE : La programmation est plus propre car le problème à résoudre n'est pas noyé dans des instructions de test mais encadré par des commandes de type try - catch.
 

Fonctions et procédures

Il est possible de définir des fonctions ou procédures sur des tables. Elles prennent des arguments qui peuvent être des champs des tables et peuvent retourner une valeur dans le cas des procédures.

On les déclare par les instructions :
CREATE OR REPLACE FUNCTION nom({args}*) RETURN TYPE_RETOUR IS variable_retour TYPE_RETOUR BEGIN ... END;
CREATE OR REPLACE PROCEDURE nom({args}*) IS variable_retour TYPE_RETOUR BEGIN ... END;
L'appel d'un programme peut se faire de différentes manières : dans un bloc PL/SQL, dans une autre routine, dans un programme C avec l'interface Pro*C etc.
Les fonctions et procédures cataloguées sont des routines PL/SQL qui sont compilées et stockées dans le dictionnaire de données. Si un objet du dictionnaire de données a été modifié dans le code, le noyau recompile le programme.

Cette manière de faire présente 4 avantages :

AVANTAGE : Sécurité : les droits d'accès ne portent plus sur des objets mais sur des programmes stockés (instruction GRANT).
AVANTAGE : Intégrité : les traitements dépendants sont exécutés dans un même bloc ===> utilisation possible de commit et rollback.
AVANTAGE : Performance : réduction du nombre d'accès à la base et utilisation d'un programme partagé.
AVANTAGE : Productivité : modularité ===> simplification de la maintenance, extensibilité et réutilisabilité.

Paquetages

Un paquetage ("package") permet de regrouper des structures de données et des programmes au sein d'un module unique. On peut y inclure des variables, des constantes, des curseurs, des procédures, des fonctions et des exceptions.

Un paquetage est composé de deux parties :
la partie spécification (interface) : contient les déclarations des programmes mis à disposition des utilisateurs.
la partie corps (implémentation) : contient les programmes publics et privés.
Les avantages des paquetages sont nombreux : sécurité, intégrité, performance, productivité, ...

Déclencheurs

Les déclencheurs ("trigger") lancent l'exécution de programmes en fonction d'événements particuliers. Dans un contexte objet-relationnel, les déclencheurs aident à la programmation de l'encapsulation et du comportement des objets.

Chaque déclencheur est associé à une table. Il se compose de deux parties : une partie qui décrit l'événement qui va réveiller le déclencheur et une partie qui décrit les traitements à effectuer le cas échéant.

Les déclencheurs sont de deux types :
les row triggers qui se déclenchent après chaque modification de la base de données
les statement triggers qui ne se déclenchent qu'après une série de modifications correspondant à l'exécution d'une requête UPDATE par exemple.
Un déclencheur peut être créé, modifié, supprimé, activé ou désactivé.

Un déclencheur de type "row" peut avoir accès aux valeurs avant et après modification des données de la BD.

Enfin, on peut regrouper des déclencheurs selon le type d'événement les produisant (INSERT, UPDATE, DELETE) grâce à des clauses adaptées.

Le déclencheur INSTEAD OF permet l'insertion, la modification et la suppression d'enregistrements d'une vue relationnelle ou objet-relationnelle multitable. De cette manière, les vues objet-relationnelles sont maintenues à jour au fur et à mesure des modifications de la base de données. Les commandes SQL classiques sont interceptées et remplacées.
C'est nouveau avec la version 8.

AVANTAGE : Mécanisme intéressant pour les applications qui mettent en oeuvre des BD distribuées. Il est désormais possible de gérer des informations réparties.
 

Programmes externes

Dans Oracle 8, on a ajouté la possibilité de faire appel à des programmes externes. On peut utiliser des routines d'un langage de troisième génération tel que C ou Cobol (voilà un langage qui a de l'avenir :-), stockées dans une librairie dynamique .DLL (win) ou .SO (unix).
Pour cela, on enregistre la librairie grâce à PL/SQL au format DLL et puis on l'enregistre dans le dictionnaire des données.
La routine est appelée comme s'il s'agissait d'un bloc "normal" PL/SQL.

AVANTAGE : Pour des raisons de sécurité, elle s'exécute dans un espace séparé de celui de la base. En C, on est en effet beaucoup plus proche de la machine...
 

 

2.4.2. Programmation des méthodes.

On peut programmer des fonctions ou des procédures à inclure dans la définition d'un type pour être appliquées à des objets de ce type. On les déclare dans la clause CREATE TYPE et on les implémente dans la clause CREATE TYPE BODY.

Une telle méthode ne peut être déclarée publique ou privée, contrairement aux fonctions ou procédures dans les paquetages.

Dans une session multi-utilisateur, on peut interdire l'utilisation d'un type à un utilisateur, donc l'accès aux méthodes de ce type, mais on ne peut pas interdire l'utilisation de certaines méthodes seulement. La restriction de la vue des méthodes à l'extérieur est directement liée à la vue externe des types. Cette manière de faire est moins flexible qu'en Java ou en C++ qui utilisent des mots-clefs spécifiques (private, protected, friend,...) dont la portée s'étend à une méthode au moins. La granularité est plus fine.

La surcharge est permise pour une méthode de type : tant au niveau du nombre de paramètres que de leur type.

Deux fonctions particulières peuvent être implémentées pour permettre la comparaison d'objets d'un type créé par l'utilisateur :

Fonction MAP.

Cette fonction sera appelée implicitement  lors d'une comparaison entre deux objets r1 et r2 du type (r1 > r2) par exemple.

Fonction ORDER.

Cette fonction à un paramètre compare l'objet en paramètre à l'objet instance de type qui appelle cette fonction. (SELF joue le rôle de this en Java).

CREATE TYPE machin_type AS OBJECT (....
ORDER MEMBER FUNCTION compare(x machin_type) RETURN INTEGER)

CREATE TYPE BODY machin_type AS
    ORDER MEMBER FUNCTION compare(x machin_type)
    RETURN INTEGER IS
    BEGIN
        IF x.value > SELF.value THEN
            RETURN -1;
        ELSIF x.value < SELF.value THEN
            RETURN 1;
        ELSE
            RETURN 0;
        END IF;
    END compare;
END;

On l'appelera comme suit :

DECLARE
    x machin_type
    y machin_type
BEGIN
    IF (x.compare(y) = -1) ...
END

 

2.4.3. Vues objet-relationnelles.

Les différences avec une vue relationnelle sont :
on peut les modifier grâce à un déclencheur de type INSTEAD OF (gestion multitable).
on peut les définir à partir d'un type, d'une table objet-relationnelle ou d'une autre vue objet-relationnelle
On crée une vue objet-relationnelle par l'instruction CREATE VIEW en spécifiant le nom de la vue, le type source et les requêtes qui la définissent. Les vues ainsi créées ne sont pas persistantes.

Pour créer une vue objet-relationnelle de tables relationnelles, on peut utiliser la clause MAKE_REF qui crée une référence à un objet d'une table. On peut utiliser une clause CAST qui transforme un type en un autre.

Bref, pour définir une vue objet-relationnelle, il faut :
définir un type (optionnel)
éxécuter une requête qui spécifie les données et les tables mises en oeuvre pour créer les objets de la vue
spécifier un identifiant (OID)
programmer des déclencheurs de type INSTEAD OF (optionnel)