Le langage PL-SQL

Contenu du cours

    •   Objectifs du PL/SQL
    •   Variables, structures de contrôle
    •   Curseurs, interaction avec la base
    •   Sous-programmes, paquetages
    •   Exceptions
    •   Déclencheurs (triggers)

PL /SQL est un langage procédural propriétaire d’Oracle qui intègre des ordres SQL. Il permet l’utilisation des
blocs SQL et d’exprimer des règles de gestion complexes sous forme de procédures stockées et de triggers.

Structure d’un bloc PL/SQL

Programme PL/SQL = bloc (procédure anonyme, procédure nommée, fonction nommée) :

PL/SQL n’interprète pas une commande, mais un ensemble de commandes contenues dans un bloc PL/SQL. Ce
bloc peut comporter plusieurs sous blocs.

        DECLARE

                -- section de déclarations
                -- section optionnelle …

        BEGIN

                -- traitement, avec d’éventuelles directives SQL
                -- section obligatoire …

        EXCEPTION

                -- gestion des erreurs
                -- section optionnelle …

        END;

Blocs imbriqués :

-- BLOC A
DECLARE
BEGIN
       -- BLOC B
       DECLARE
       BEGIN
              -- BLOC C
              DECLARE
              BEGIN
                     -- BLOC D
                     DECLARE
MISR-MSRS : M1                          Support du cours PL/SQL                           L. KOUTTI
BEGIN
                    -- BLOC E
                    DECLARE
                    BEGIN
                    EXCEPTION
                    END;
               EXCEPTION
               END;
          EXCEPTION
          END;
     EXCEPTION
     END;
EXCEPTION
END;

Portée d’un identificateur :

Le bloc E peut accéder aux identificateurs déclarés dans les blocs D, C, B et A. L’inverse n’est pas vrai.

Identificateurs, commentaires
Un identificateur (variable, curseur, exception, etc.) :
       - Commence par une lettre
       - Peut contenir : lettres, chiffres, $, #, _
       - Interdits : &, -, /, espace
       - Jusqu’à 30 caractères
       - Insensible à la casse !
On peut documenter un code PL/SQL. Les différentes façons d’introduire des commentaires :
       - -- Commentaire sur une seule ligne
       - /* Commentaire sur plusieurs
            lignes */

Les variables PL/SQL

PL/SQL permet de déclarer et de manipuler des variables.

Types de variables PL/SQL :

Scalaires : par exemple NUMBER (5,2), VARCHAR2, DATE, BOOLEAN, CHAR…

Composites : %ROWTYPE, RECORD, TABLE

Toute variable PL/SQL doit obligatoirement être déclarée avant utilisation. Cette déclaration s’effectue dans la
zone DECLRAE.

Exemple :

                       vNumero                 NUMBER(5) ;
                       vNom                    VARCHAR2(12) ;
                       vDateNaissance          DATE ;
                       vPoids                  NUMBER(5,2) ;
                       vSexe                   CHAR(1) ;

Déclaration %TYPE


MISR-MSRS : M1                          Support du cours PL/SQL                              L. KOUTTI
PL/SQL permet de déclarer des variables faisant références à la colonne d’une table, il permet de récupérer
automatiquement le type de la donnée tel qu’il est défini dans le dictionnaire de la base. Cette propagation du
type permet de réduire le nombre de changements à apporter au code PL/SQL en cas de modification des types
de certaines colonnes.

Exemple :

Soit la table SALARIES suivante :

               SALARIES
               salnumero
               salnom
               salprenom
               saladresse
               salsalaire
               salcomm


                   create table salaries (
                    salnumero       number not null,
                    salnom          varchar (15),
                    salprenom       varchar (15),
                    saladresse      varchar (40),
                    salsalaire      number (7, 2),
                    salcomm         number (7, 2),
                    constraint      pk_salaries primary key (salnumero)
                   );


                  DECLARE
                        vNomClient        salaries.salnom%TYPE;
                        vSalClient        salaries.salsalaire%TYPE;
                  BEGIN
                        SELECT            salnom, salsalaire
                        INTO              vNomClient, vSalClient
                        FROM              salaries
                        WHERE             salnumero = 1000;
                  END;


Déclaration %ROWTYPE


PL/SQL permet de déclarer une variable composite de même type que les tuples d’une table.

                      vEnreg salaries%ROWTYPE;
Les composantes de la variable composite, identifiées par vEnreg.nomColonne, sont du même type que les
colonnes correspondantes de la table.

Exemple :
               DECLARE
               vEenregSalaries salaries%ROWTYPE;
               BEGIN
               vEenregSalaries.salnumero   = 1200;
               vEenregSalaries.salnom      = 'VAUDAN';
               vEenregSalaries.salprenom   = 'STEPHANE';
               vEenregSalaries.saladresse  = '37, RUE PIERRE AVIA PARIS';

MISR-MSRS : M1                        Support du cours PL/SQL                             L. KOUTTI
vEenregSalaries.salcomm     = 120;
                INSERT INTO salaries vEenregSalaries ;
                END;



Affectation des valeurs aux variables PL/SQL

On peut affecter des valeurs aux variables PL/SQL soit :

        -   En utilisant l’opérateur d’assignation :=

                       vAge            := SYSDATE – vDateNaissance ;
                       vNomSalarie     := UPPER ('Nom') ;

        -   A partir d’un ordre SELECT

                       …
                        SELECT    salnom, saladresse
                        INTO      vNom, vAdresse
                        FROM      salaries
                        WHERE     salnumero = 1200 ;
                       …

Remarque:

L’ordre SELECT doit retourner une seule ligne, dans le cas contraire une erreur est générée.

Structures de contrôle
Traitement conditionnelle


Syntaxe:

                       IF condition_1 THEN
                         Instructions_1;
                       ELSIF condition_2
                         Instructions_2;
                       ELSE
                         Instructions_3;
                       END IF;
Les opérateurs relationnels sont: =, <, >, !=, >=, <=, IS NULL, IS NOT NULL, BETWEEN, LIKE, AND, OR




MISR-MSRS : M1                          Support du cours PL/SQL                            L. KOUTTI
Exemple :
                      DECLARE
                       vSalaire salsalaire.salaries%TYPE;
                      BEGIN
                       SELECT salsalaire
                       INTO      vSalaire
                       FROM salaries
                       WHERE salnumero = 1200;

                       IF vSalaire < 1000 THEN
                         UPDATE salaries
                         SET       salsalaire = salsalaire*1.1
                         WHERE salnumero = 1200;
                       ELSIF vSalaire BETWEEN 1000 AND 3000 THEN
                         UPDATE salaries
                         SET salsalaire = salsalaire*1.05
                         WHERE salnumero = 1200;
                       ELSE
                         UPDATE salaries
                         SET salcomm = salcomm + 100
                         WHERE salnumero = 1200;
                       END IF;
                      END;


Structures répétitives : la boucle de base


PL/SQL permet d’effectuer des traitements répétitifs grâce à la clause LOOP.

                      BEGIN
                      …
                       LOOP
                        Instructions
                       END LOOP;
                      …
                      END;
Remarque :

La boucle ci-dessus s’exécute indéfiniment, l’instruction EXIT permet de stopper l’exécution de la boucle
LOOP.

                     BEGIN                                  BEGIN
                     …                                      …
                      LOOP                                   LOOP
                       Instructions                           Instructions
                       EXIT WHEN condition;                   IF condition THEN
                      END LOOP;                                EXIT;
                     …                                        END IF;
                     END;                                    END LOOP;
                                                            …
                                                            END;
Structures répétitives : la boucle FOR


Syntaxe :

MISR-MSRS : M1                         Support du cours PL/SQL                       L. KOUTTI
FOR compteur IN val_1..val_2
                       LOOP
                         instructions;
                       END LOOP;

Structures répétitives : la boucle WHILE


                       WHILE condition
                       LOOP
                        instructions;
                       END LOOP;

La condition est vérifiée au début de chaque itération ; tant que la condition est vérifiée, les instructions sont
exécutées.

Les curseurs

Un curseur est une zone mémoire de taille fixe capable de stocker plusieurs enregistrements et de gérer l’accès à
ces enregistrements.

Types de curseurs :


    -   Curseurs implicites :
         Déclarés implicitement et manipulés par SQL pour toute requête SQL et pour les interrogations qui
        retournent un seul enregistrement
    -   Curseurs explicites :
         Déclarés et manipulés par l’utilisateur pour les interrogations qui retournent plus d’un enregistrement

Etapes d’utilisation d’un curseur :


    -   Déclaration
    -   Ouverture
    -   Traitement des lignes
    -   Fermeture

Déclaration d’un curseur
Syntaxe :

                       CURSOR nom_curseur IS requête ;



Cette déclaration se fait dans la section DECLARE.

Exemple :

                       DECLARE
                        CURSOR c_salaries IS
                        SELECT salnumero, salnom, salsalaire
                        FROM salaries;

MISR-MSRS : M1                          Support du cours PL/SQL                               L. KOUTTI
BEGIN
                        …
                       END;



L’ensemble de lignes renvoyées par une interrogation multi lignes s’appelle un result set (jeu de résultats).


                                                   ResultSet

            Curseur        1100                    VAUDAN                  20000
                           1200                    HOMEYER                 30000
                           1300                    BUELLET                 40000


Ouverture d’un curseur
Elle permet :

   - L’allocation mémoire du curseur,
   - L’analyse syntaxique et sémantique de la requête,
   - Elle se fait dans la section BEGIN.
Syntaxe :

                       OPEN c_salaries ;
Exemple :

                       DECLARE
                        CURSOR c_salaries IS
                        SELECT salnumero, salnom, salsalaire
                        FROM salaries;
                       BEGIN
                        OPEN c_salaries;
                        …
                       END;

Traitement des lignes
Les lignes retournées par l’ordre SELECT sont traitées une par une. La valeur de chaque colonne doit être
stockée dans une variable réceptrice.

Syntaxe :

                       FETCH c_salaries INTO variables_receptrices ;



La clause FETCH ne récupère qu’un seul enregistrement. Pour accéder à l’ensemble des lignes de l’ordre
SELECT, il faut prévoir une boucle.

Le traitement des lignes se fait dans le corps du bloc PL/SQL.




MISR-MSRS : M1                          Support du cours PL/SQL                               L. KOUTTI
Exemple :

                       DECLARE
                        vNumero salnumero.salaries%TYPE;
                        vSalaire salsalaire.salaries%TYPE;
                        -- Déclaration du curseur
                        CURSOR c_salaries IS
                        SELECT salnumero, salsalaire
                        FROM       salaries
                        ORDER BY salsalaire;

                       BEGIN

                        OPEN c_salaries;
                        LOOP
                         FETCH c_salaries
                         INTO vNumero, vSalaire;

                         IF vSalaire < 1000 THEN
                           UPDATE salaries
                           SET salsalaire = salsalaire*1.1
                           WHERE salnumero = vNumero;
                         ELSIF vSalaire BETWEEN 1000 AND 3000 THEN
                           UPDATE salaries
                           SET salsalaire = salsalaire*1.05
                           WHERE salnumero = vNumero;
                         END IF;
                         EXIT WHEN vSalaire > 3000
                        END LOOP;
                       END;

Fermeture d’un curseur


Syntaxe :
                       CLOSE c_salaries;

Libération de la place mémoire allouée.

Attributs d’un curseur:
Les attributs permettent de connaître l’état d’un curseur.

%FOUND et %NOTFOUND déterminent si toutes les lignes retournées par le curseur ont étés traitées.

%ISOPEN précise si le curseur est ouvert.

%ROWCOUNT indique le nombre de lignes déjà traitées.

Curseurs explicites paramétrés

Objectif : paramétrer la requête associée à un curseur pour éviter de multiplier les curseurs similaires dans le
même bloc PL/SQL.
Syntaxe :
                       CURSOR nom_curseur (param1 type1, param2 type2, …]) IS …;



MISR-MSRS : M1                          Support du cours PL/SQL                            L. KOUTTI
Les valeurs des paramètres sont transmises à l’ouverture du curseur :

                      OPEN nom_curseur (valeurPar1, valeurPar2, …);


Il faut évidemment fermer le curseur avant de l’appeler avec d’autres valeurs pour les paramètres.

Simplification d’écriture des curseurs


Exemple :


          DECLARE
           CURSOR c_salaries IS
           SELECT salnumero, salsalaire
           FROM salaries
           ORDER BY salsalaire;
           --Déclaration d’une structure
           enreg_salaries c_salaries%ROWTYPE;
          BEGIN
           OPEN c_salaries;
           LOOP
            FETCH c_salaries INTO enreg_salaries;
            IF enreg_salaries.salsalaire < 1000 THEN
              UPDATE salaries
              SET salsalaire = salsalaire*1.1
              WHERE salnumero = enreg_salaries.salnumero;
            ELSIF enreg_salaries.salsalaire BETWEEN 1000 AND 3000 THEN
              UPDATE salaries
              SET salsalaire = salsalaire*1.05
              WHERE salnumero = enreg_salaries.salnumero;
            END IF;
            EXIT WHEN c_salaries%NOTFOUND ;
           END LOOP;
           CLOSE c_salaries;
          END;

Simplification d’écriture des curseurs : utilisation de la boucle FOR..IN

            DECLARE

            BEGIN
             FOR enreg_salaries IN (                 SELECT salnumero, salsalaire
                                                     FROM salaries
                                                     ORDER BY salsalaire
                                     )
             LOOP
              IF enreg_salaries.salsalaire < 1000 THEN
               UPDATE salaries
               SET salsalaire = salsalaire*1.1
               WHERE salnumero = enreg_salaries.salnumero;
              ELSIF enreg_salaries.salsalaire BETWEEN 1000 AND 3000 THEN
               UPDATE salaries
               SET salsalaire = salsalaire*1.05
               WHERE salnumero = enreg_salaries.salnumero;
              END IF;

MISR-MSRS : M1                         Support du cours PL/SQL                              L. KOUTTI
END LOOP;
            END;


Procédures et fonctions

Ce sont les sous programmes hébergés par la base de données : ils peuvent être appelés à partir d’une autre
procédure, fonction ou encore depuis un programme exécutable extérieur à la base de données.

Un sous programme est un bloc PL/SQL nommé qui peut accepter des paramètres et être appelé.

Procédures
Syntaxe :



             PROCEDURE laProcedure (param1 IN | OUT | IN type 1, param2…) IS
             BEGIN
              …
             EXCEPTION
             END;

Une procédure se termine à la fin du bloc ou par une instruction RETURN.

Fonctions
Syntaxe :

FUNCTION laFonction (param1 IN | OUT | IN type 1, param2…)RETURN type_variable IS
BEGIN
 …
EXCEPTION
END;

Une fonction se termine par l’instruction RETURN qui doit renvoyer un résultat.

Remarque :

Comme tout objet SQL, une procédure ou une fonction peut être créée, modifiée ou supprimée.

Création
                   CREATE PROCEDURE…
                   CREATE FUNCTION…



Modification

                   CREATE OR REPLACE PROCEDURE…
                   CREATE OR REPLACE FUNCTION…

Suppression

                   DROP PROCEDURE…
                   DROP FUNCTION…


MISR-MSRS : M1                           Support du cours PL/SQL                              L. KOUTTI
Exécution et utilisation de procédures et de fonctions

             SQL> CREATE OR REPLACE FUNCTION leDouble (p_telNombre IN NUMBER)
             RETURN NUMBER IS
             le_double NUMBER;
             BEGIN
               le_double := p_telNombre*2;
               RETURN le_double;
             END ;
             /



             SQL> DECLARE
             v_leNombre NUMBER := 12;
             v_ledouble NUMBER;
             BEGIN
               le_double := leDouble(v_telNombre);
             END ;
             /

Remarques :

 -   Pour repérer les erreurs, on dispose de la commande SHOW ERRORS.

 -   Pour afficher les variables contenues dans un bloc PL/SQL, il faut inclure le package (définit plus loin)
     standard dbms_output.put_line.



Paquetages

Un paquetage PL/SQL permet de regrouper un ensemble de procédures, de fonctions, de variables et de curseurs
au sein d’un ensemble cohérent de services.

 -   Distinction entre ce qui est accessible depuis l’extérieur et ce qui n’est accessible qu’à l’intérieur du
     paquetage : encapsulation

 -   Structure :

         o    Section de spécification : déclarations des variables, curseurs, sous-programmes accessibles depuis
              l’extérieur,

         o    Section d’implémentation : code des sous-programmes accessibles depuis l’extérieur + sous-
              programmes accessibles en interne (privés)

Il y a des packages prédéfinis :

Parmi eux, le package DBMS_OUTPUT : affichage pour la mise au point des programmes PL/SQL. Il est
utilisé pour envoyer des messages contrôlant l’exécution d’un programme PL/SQL ou en encore lors du
débogage.


MISR-MSRS : M1                           Support du cours PL/SQL                                L. KOUTTI
Exceptions

PL/SQL permet de définir dans une zone particulière (de gestion d’exception), l’attitude que le programme doit
avoir lorsque certaines erreurs définies ou prédéfinies se produisent.

Un certain nombre d’exceptions sont prédéfinies sous Oracle. Citons, pour les plus fréquentes :
NO_DATA_FOUND (devient vrai dès qu’une requête renvoie un résultat vide), TOO_MANY_ROWS
(requête renvoie plus de lignes qu’escompté), CURSOR_ALREADY_OPEN (curseur déjà ouvert),
INVALID_CURSOR (curseur invalide)...

L’utilisateur peut définir ses propres exceptions. Dans ce cas, il doit définir celles ci dans la zone de déclaration.

Exemple :

        v_exception EXCEPTION ;

Puis, cette exception est levée quelque part dans le programme (après un test non concluant, par exemple), par
l’instruction :

        RAISE v_exception ;

Enfin, dans la zone d’exception un traitement est affecté à chaque exception possible (définie ou prédéfinie) :


                   EXCEPTION
                    WHEN <exception1> [OR <exception2> OR ...] THEN <instructions>
                    WHEN <exception3> [OR <exception2> OR ...] THEN <instructions>
                    WHEN OTHERS THEN <instructions>
                   END;




Evidemment, un seul traitement d’exception peut se produire avant la sortie du bloc.

Les exceptions internes

Une erreur interne est produite quand un bloc PL/SQL viole une règle d'Oracle ou dépasse une limite dépendant
du système d'exploitation.

Les erreurs Oracle générées par le noyau sont numérotées, or le gestionnaire des exceptions de PL/SQL, ne sait
que gérer des erreurs nommées.

Pour cela PL/SQL a redéfini quelques erreurs Oracle comme des exceptions. Ainsi, pour gérer d'autres erreurs
Oracle, l'utilisateur doit utiliser le gestionnaire OTHERS ou EXCEPTION_INIT pour nommer ces erreurs.

Les exceptions fournies par Oracle sont regroupées dans ce tableau :

                                Nom d'exception               Valeur Sql Code Erreur Oracle
                       CURSOR_ALREADY_OPEN                    -6511              ORA-06511
                       DUP_VAL_ON_INDEX                       -1                 ORA-00001
                       INVALID_CURSOR                         -1001              ORA-01001


MISR-MSRS : M1                           Support du cours PL/SQL                                 L. KOUTTI
INVALID_NUMBER                       -1722             ORA-01722
                      LOGIN_DENIED                         -1017             ORA-01717
                      NO_DATA_FOUND                        -1403             ORA-01413
                      NOT_LOGGED_ON                        -1012             ORA-01012
                      PROGRAM_ERROR                        -6501             ORA-06501
                      STORAGE_ERROR                        -6500             ORA-06500
                      TIMEOUT_ON_RESOURCE                  -51               ORA-00051
                      TOO_MANY_ROWS                        -1422             ORA-01422
                      TRANSACTION_BACKED_OUT -61                             ORA-00061
                      VALUE_ERROR                          -6502             ORA-06502
                      ZERO_DIVIDE                          -1476             ORA-01476


OTHERS : toutes les autres erreurs non explicitement nommées.

Pour gérer les exceptions, le développeur doit écrire un gestionnaire des exceptions qui prend le contrôle du
déroulement du bloc PL/SQL en présence d'une exception.

Le gestionnaire d'exception fait partie du bloc PL/SQL et se trouve après les commandes.

Il commence par le mot clé EXCEPTION et se termine avec le même END du bloc.

Chaque gestion d'exception consiste à spécifier son nom d'erreur après la clause WHEN et la séquence de la
commande à exécuter après le mot clé THEN, comme le montre l'exemple suivant :

Les déclencheurs (“triggers”)

Les déclencheurs ou ”triggers” sont des séquences d’actions définis par le programmeur qui se déclenchent, sur
des actions modifiant les données de la table sur laquelle porte le trigger.

Un trigger sera un objet stocké (comme une table ou une procédure).

Syntaxe :

                  CREATE [OR REPLACE] TRIGGER <nomTrg>
                  {BEFORE|AFTER} {INSERT|DELETE|UPDATE} ON <nomTable>
                  [FOR EACH ROW [WHEN (<condition>)]]
                  <corps du trigger>

Le type d’action qui déclenche le trigger détermine son moment d’exécution : il est précisé au début de l’écriture
du code de trigger.

(INSERT|DELETE|UPDATE)

Le trigger peut être déclenché avant ou après cette action (BEFORE|AFTER)




MISR-MSRS : M1                         Support du cours PL/SQL                               L. KOUTTI
L’option FOR EACH ROW [WHEN (<condition>)] fait exécuter le trigger à chaque modification d’une ligne
de la table spécifiée (on dit que le trigger est de ”niveau ligne”). En l’absence de cette option, le trigger est
exécuté une seule fois (”niveau table”).

Caractéristiques


    •   Un déclencheur a un nom.
    •   Il est associé à une table et une seule.
    •   Il peut être actif ou inactif.
    •   Il est opérationnel jusqu’à sa suppression ou la suppression de la table à laquelle il est associé.

Référence aux colonnes d’une table


    •   Dans le code associé aux déclencheurs de niveau ligne, on peut accéder aux valeurs des attributs de la
        ligne modifiée par les variables :
                :old et :new
    •   Pour un déclencheur sur INSERT, les nouvelles valeurs sont dans :new.<nom attribut>
    •   Pour un déclencheur sur UPDATE, les anciennes valeurs sont dans :old.<nom d’attribut>. Les
        nouvelles valeurs sont dans :new.<nom d’attribut>
    •   Pour un déclencheur sur DELETE, les anciennes valeurs sont dans :old.<nom d’attribut>

Remarques

    •   N’utilisez pas les triggers pour effectuer des contrôles d’intégrité.
    •   Pour éviter de supprimer et recréer un trigger : create or replace trigger
    •   Pour un trigger relatif à plusieurs événements, utiliser les prédicats inserting, updating, deleting

                   if inserting then …end if;
                   if updating then …end if;
                   if deleting then …end if;

Activer/désactiver
       Un trigger est crée par la clause CREATE TRIGGER ou CREATE OR REPLACE TRIGGER. Un
       trigger existant peut être détruit par DROP TRIGGER.


                 ALTER TRIGGER nomTrigger ENABLE; -- active le trigger
                 ALTER TRIGGER nomTrigger DISABLE; -- désactive le trigger
                 ALTER TABLE nomTable ENABLE ALL TRIGGERS;
                 ALTER TABLE nomTable DISABLE ALL TRIGGERS;




MISR-MSRS : M1                           Support du cours PL/SQL                                L. KOUTTI

Le langage plsql

  • 1.
    Le langage PL-SQL Contenudu cours • Objectifs du PL/SQL • Variables, structures de contrôle • Curseurs, interaction avec la base • Sous-programmes, paquetages • Exceptions • Déclencheurs (triggers) PL /SQL est un langage procédural propriétaire d’Oracle qui intègre des ordres SQL. Il permet l’utilisation des blocs SQL et d’exprimer des règles de gestion complexes sous forme de procédures stockées et de triggers. Structure d’un bloc PL/SQL Programme PL/SQL = bloc (procédure anonyme, procédure nommée, fonction nommée) : PL/SQL n’interprète pas une commande, mais un ensemble de commandes contenues dans un bloc PL/SQL. Ce bloc peut comporter plusieurs sous blocs. DECLARE -- section de déclarations -- section optionnelle … BEGIN -- traitement, avec d’éventuelles directives SQL -- section obligatoire … EXCEPTION -- gestion des erreurs -- section optionnelle … END; Blocs imbriqués : -- BLOC A DECLARE BEGIN -- BLOC B DECLARE BEGIN -- BLOC C DECLARE BEGIN -- BLOC D DECLARE MISR-MSRS : M1 Support du cours PL/SQL L. KOUTTI
  • 2.
    BEGIN -- BLOC E DECLARE BEGIN EXCEPTION END; EXCEPTION END; EXCEPTION END; EXCEPTION END; EXCEPTION END; Portée d’un identificateur : Le bloc E peut accéder aux identificateurs déclarés dans les blocs D, C, B et A. L’inverse n’est pas vrai. Identificateurs, commentaires Un identificateur (variable, curseur, exception, etc.) : - Commence par une lettre - Peut contenir : lettres, chiffres, $, #, _ - Interdits : &, -, /, espace - Jusqu’à 30 caractères - Insensible à la casse ! On peut documenter un code PL/SQL. Les différentes façons d’introduire des commentaires : - -- Commentaire sur une seule ligne - /* Commentaire sur plusieurs lignes */ Les variables PL/SQL PL/SQL permet de déclarer et de manipuler des variables. Types de variables PL/SQL : Scalaires : par exemple NUMBER (5,2), VARCHAR2, DATE, BOOLEAN, CHAR… Composites : %ROWTYPE, RECORD, TABLE Toute variable PL/SQL doit obligatoirement être déclarée avant utilisation. Cette déclaration s’effectue dans la zone DECLRAE. Exemple : vNumero NUMBER(5) ; vNom VARCHAR2(12) ; vDateNaissance DATE ; vPoids NUMBER(5,2) ; vSexe CHAR(1) ; Déclaration %TYPE MISR-MSRS : M1 Support du cours PL/SQL L. KOUTTI
  • 3.
    PL/SQL permet dedéclarer des variables faisant références à la colonne d’une table, il permet de récupérer automatiquement le type de la donnée tel qu’il est défini dans le dictionnaire de la base. Cette propagation du type permet de réduire le nombre de changements à apporter au code PL/SQL en cas de modification des types de certaines colonnes. Exemple : Soit la table SALARIES suivante : SALARIES salnumero salnom salprenom saladresse salsalaire salcomm create table salaries ( salnumero number not null, salnom varchar (15), salprenom varchar (15), saladresse varchar (40), salsalaire number (7, 2), salcomm number (7, 2), constraint pk_salaries primary key (salnumero) ); DECLARE vNomClient salaries.salnom%TYPE; vSalClient salaries.salsalaire%TYPE; BEGIN SELECT salnom, salsalaire INTO vNomClient, vSalClient FROM salaries WHERE salnumero = 1000; END; Déclaration %ROWTYPE PL/SQL permet de déclarer une variable composite de même type que les tuples d’une table. vEnreg salaries%ROWTYPE; Les composantes de la variable composite, identifiées par vEnreg.nomColonne, sont du même type que les colonnes correspondantes de la table. Exemple : DECLARE vEenregSalaries salaries%ROWTYPE; BEGIN vEenregSalaries.salnumero = 1200; vEenregSalaries.salnom = 'VAUDAN'; vEenregSalaries.salprenom = 'STEPHANE'; vEenregSalaries.saladresse = '37, RUE PIERRE AVIA PARIS'; MISR-MSRS : M1 Support du cours PL/SQL L. KOUTTI
  • 4.
    vEenregSalaries.salcomm = 120; INSERT INTO salaries vEenregSalaries ; END; Affectation des valeurs aux variables PL/SQL On peut affecter des valeurs aux variables PL/SQL soit : - En utilisant l’opérateur d’assignation := vAge := SYSDATE – vDateNaissance ; vNomSalarie := UPPER ('Nom') ; - A partir d’un ordre SELECT … SELECT salnom, saladresse INTO vNom, vAdresse FROM salaries WHERE salnumero = 1200 ; … Remarque: L’ordre SELECT doit retourner une seule ligne, dans le cas contraire une erreur est générée. Structures de contrôle Traitement conditionnelle Syntaxe: IF condition_1 THEN Instructions_1; ELSIF condition_2 Instructions_2; ELSE Instructions_3; END IF; Les opérateurs relationnels sont: =, <, >, !=, >=, <=, IS NULL, IS NOT NULL, BETWEEN, LIKE, AND, OR MISR-MSRS : M1 Support du cours PL/SQL L. KOUTTI
  • 5.
    Exemple : DECLARE vSalaire salsalaire.salaries%TYPE; BEGIN SELECT salsalaire INTO vSalaire FROM salaries WHERE salnumero = 1200; IF vSalaire < 1000 THEN UPDATE salaries SET salsalaire = salsalaire*1.1 WHERE salnumero = 1200; ELSIF vSalaire BETWEEN 1000 AND 3000 THEN UPDATE salaries SET salsalaire = salsalaire*1.05 WHERE salnumero = 1200; ELSE UPDATE salaries SET salcomm = salcomm + 100 WHERE salnumero = 1200; END IF; END; Structures répétitives : la boucle de base PL/SQL permet d’effectuer des traitements répétitifs grâce à la clause LOOP. BEGIN … LOOP Instructions END LOOP; … END; Remarque : La boucle ci-dessus s’exécute indéfiniment, l’instruction EXIT permet de stopper l’exécution de la boucle LOOP. BEGIN BEGIN … … LOOP LOOP Instructions Instructions EXIT WHEN condition; IF condition THEN END LOOP; EXIT; … END IF; END; END LOOP; … END; Structures répétitives : la boucle FOR Syntaxe : MISR-MSRS : M1 Support du cours PL/SQL L. KOUTTI
  • 6.
    FOR compteur INval_1..val_2 LOOP instructions; END LOOP; Structures répétitives : la boucle WHILE WHILE condition LOOP instructions; END LOOP; La condition est vérifiée au début de chaque itération ; tant que la condition est vérifiée, les instructions sont exécutées. Les curseurs Un curseur est une zone mémoire de taille fixe capable de stocker plusieurs enregistrements et de gérer l’accès à ces enregistrements. Types de curseurs : - Curseurs implicites : Déclarés implicitement et manipulés par SQL pour toute requête SQL et pour les interrogations qui retournent un seul enregistrement - Curseurs explicites : Déclarés et manipulés par l’utilisateur pour les interrogations qui retournent plus d’un enregistrement Etapes d’utilisation d’un curseur : - Déclaration - Ouverture - Traitement des lignes - Fermeture Déclaration d’un curseur Syntaxe : CURSOR nom_curseur IS requête ; Cette déclaration se fait dans la section DECLARE. Exemple : DECLARE CURSOR c_salaries IS SELECT salnumero, salnom, salsalaire FROM salaries; MISR-MSRS : M1 Support du cours PL/SQL L. KOUTTI
  • 7.
    BEGIN … END; L’ensemble de lignes renvoyées par une interrogation multi lignes s’appelle un result set (jeu de résultats). ResultSet Curseur 1100 VAUDAN 20000 1200 HOMEYER 30000 1300 BUELLET 40000 Ouverture d’un curseur Elle permet : - L’allocation mémoire du curseur, - L’analyse syntaxique et sémantique de la requête, - Elle se fait dans la section BEGIN. Syntaxe : OPEN c_salaries ; Exemple : DECLARE CURSOR c_salaries IS SELECT salnumero, salnom, salsalaire FROM salaries; BEGIN OPEN c_salaries; … END; Traitement des lignes Les lignes retournées par l’ordre SELECT sont traitées une par une. La valeur de chaque colonne doit être stockée dans une variable réceptrice. Syntaxe : FETCH c_salaries INTO variables_receptrices ; La clause FETCH ne récupère qu’un seul enregistrement. Pour accéder à l’ensemble des lignes de l’ordre SELECT, il faut prévoir une boucle. Le traitement des lignes se fait dans le corps du bloc PL/SQL. MISR-MSRS : M1 Support du cours PL/SQL L. KOUTTI
  • 8.
    Exemple : DECLARE vNumero salnumero.salaries%TYPE; vSalaire salsalaire.salaries%TYPE; -- Déclaration du curseur CURSOR c_salaries IS SELECT salnumero, salsalaire FROM salaries ORDER BY salsalaire; BEGIN OPEN c_salaries; LOOP FETCH c_salaries INTO vNumero, vSalaire; IF vSalaire < 1000 THEN UPDATE salaries SET salsalaire = salsalaire*1.1 WHERE salnumero = vNumero; ELSIF vSalaire BETWEEN 1000 AND 3000 THEN UPDATE salaries SET salsalaire = salsalaire*1.05 WHERE salnumero = vNumero; END IF; EXIT WHEN vSalaire > 3000 END LOOP; END; Fermeture d’un curseur Syntaxe : CLOSE c_salaries; Libération de la place mémoire allouée. Attributs d’un curseur: Les attributs permettent de connaître l’état d’un curseur. %FOUND et %NOTFOUND déterminent si toutes les lignes retournées par le curseur ont étés traitées. %ISOPEN précise si le curseur est ouvert. %ROWCOUNT indique le nombre de lignes déjà traitées. Curseurs explicites paramétrés Objectif : paramétrer la requête associée à un curseur pour éviter de multiplier les curseurs similaires dans le même bloc PL/SQL. Syntaxe : CURSOR nom_curseur (param1 type1, param2 type2, …]) IS …; MISR-MSRS : M1 Support du cours PL/SQL L. KOUTTI
  • 9.
    Les valeurs desparamètres sont transmises à l’ouverture du curseur : OPEN nom_curseur (valeurPar1, valeurPar2, …); Il faut évidemment fermer le curseur avant de l’appeler avec d’autres valeurs pour les paramètres. Simplification d’écriture des curseurs Exemple : DECLARE CURSOR c_salaries IS SELECT salnumero, salsalaire FROM salaries ORDER BY salsalaire; --Déclaration d’une structure enreg_salaries c_salaries%ROWTYPE; BEGIN OPEN c_salaries; LOOP FETCH c_salaries INTO enreg_salaries; IF enreg_salaries.salsalaire < 1000 THEN UPDATE salaries SET salsalaire = salsalaire*1.1 WHERE salnumero = enreg_salaries.salnumero; ELSIF enreg_salaries.salsalaire BETWEEN 1000 AND 3000 THEN UPDATE salaries SET salsalaire = salsalaire*1.05 WHERE salnumero = enreg_salaries.salnumero; END IF; EXIT WHEN c_salaries%NOTFOUND ; END LOOP; CLOSE c_salaries; END; Simplification d’écriture des curseurs : utilisation de la boucle FOR..IN DECLARE BEGIN FOR enreg_salaries IN ( SELECT salnumero, salsalaire FROM salaries ORDER BY salsalaire ) LOOP IF enreg_salaries.salsalaire < 1000 THEN UPDATE salaries SET salsalaire = salsalaire*1.1 WHERE salnumero = enreg_salaries.salnumero; ELSIF enreg_salaries.salsalaire BETWEEN 1000 AND 3000 THEN UPDATE salaries SET salsalaire = salsalaire*1.05 WHERE salnumero = enreg_salaries.salnumero; END IF; MISR-MSRS : M1 Support du cours PL/SQL L. KOUTTI
  • 10.
    END LOOP; END; Procédures et fonctions Ce sont les sous programmes hébergés par la base de données : ils peuvent être appelés à partir d’une autre procédure, fonction ou encore depuis un programme exécutable extérieur à la base de données. Un sous programme est un bloc PL/SQL nommé qui peut accepter des paramètres et être appelé. Procédures Syntaxe : PROCEDURE laProcedure (param1 IN | OUT | IN type 1, param2…) IS BEGIN … EXCEPTION END; Une procédure se termine à la fin du bloc ou par une instruction RETURN. Fonctions Syntaxe : FUNCTION laFonction (param1 IN | OUT | IN type 1, param2…)RETURN type_variable IS BEGIN … EXCEPTION END; Une fonction se termine par l’instruction RETURN qui doit renvoyer un résultat. Remarque : Comme tout objet SQL, une procédure ou une fonction peut être créée, modifiée ou supprimée. Création CREATE PROCEDURE… CREATE FUNCTION… Modification CREATE OR REPLACE PROCEDURE… CREATE OR REPLACE FUNCTION… Suppression DROP PROCEDURE… DROP FUNCTION… MISR-MSRS : M1 Support du cours PL/SQL L. KOUTTI
  • 11.
    Exécution et utilisationde procédures et de fonctions SQL> CREATE OR REPLACE FUNCTION leDouble (p_telNombre IN NUMBER) RETURN NUMBER IS le_double NUMBER; BEGIN le_double := p_telNombre*2; RETURN le_double; END ; / SQL> DECLARE v_leNombre NUMBER := 12; v_ledouble NUMBER; BEGIN le_double := leDouble(v_telNombre); END ; / Remarques : - Pour repérer les erreurs, on dispose de la commande SHOW ERRORS. - Pour afficher les variables contenues dans un bloc PL/SQL, il faut inclure le package (définit plus loin) standard dbms_output.put_line. Paquetages Un paquetage PL/SQL permet de regrouper un ensemble de procédures, de fonctions, de variables et de curseurs au sein d’un ensemble cohérent de services. - Distinction entre ce qui est accessible depuis l’extérieur et ce qui n’est accessible qu’à l’intérieur du paquetage : encapsulation - Structure : o Section de spécification : déclarations des variables, curseurs, sous-programmes accessibles depuis l’extérieur, o Section d’implémentation : code des sous-programmes accessibles depuis l’extérieur + sous- programmes accessibles en interne (privés) Il y a des packages prédéfinis : Parmi eux, le package DBMS_OUTPUT : affichage pour la mise au point des programmes PL/SQL. Il est utilisé pour envoyer des messages contrôlant l’exécution d’un programme PL/SQL ou en encore lors du débogage. MISR-MSRS : M1 Support du cours PL/SQL L. KOUTTI
  • 12.
    Exceptions PL/SQL permet dedéfinir dans une zone particulière (de gestion d’exception), l’attitude que le programme doit avoir lorsque certaines erreurs définies ou prédéfinies se produisent. Un certain nombre d’exceptions sont prédéfinies sous Oracle. Citons, pour les plus fréquentes : NO_DATA_FOUND (devient vrai dès qu’une requête renvoie un résultat vide), TOO_MANY_ROWS (requête renvoie plus de lignes qu’escompté), CURSOR_ALREADY_OPEN (curseur déjà ouvert), INVALID_CURSOR (curseur invalide)... L’utilisateur peut définir ses propres exceptions. Dans ce cas, il doit définir celles ci dans la zone de déclaration. Exemple : v_exception EXCEPTION ; Puis, cette exception est levée quelque part dans le programme (après un test non concluant, par exemple), par l’instruction : RAISE v_exception ; Enfin, dans la zone d’exception un traitement est affecté à chaque exception possible (définie ou prédéfinie) : EXCEPTION WHEN <exception1> [OR <exception2> OR ...] THEN <instructions> WHEN <exception3> [OR <exception2> OR ...] THEN <instructions> WHEN OTHERS THEN <instructions> END; Evidemment, un seul traitement d’exception peut se produire avant la sortie du bloc. Les exceptions internes Une erreur interne est produite quand un bloc PL/SQL viole une règle d'Oracle ou dépasse une limite dépendant du système d'exploitation. Les erreurs Oracle générées par le noyau sont numérotées, or le gestionnaire des exceptions de PL/SQL, ne sait que gérer des erreurs nommées. Pour cela PL/SQL a redéfini quelques erreurs Oracle comme des exceptions. Ainsi, pour gérer d'autres erreurs Oracle, l'utilisateur doit utiliser le gestionnaire OTHERS ou EXCEPTION_INIT pour nommer ces erreurs. Les exceptions fournies par Oracle sont regroupées dans ce tableau : Nom d'exception Valeur Sql Code Erreur Oracle CURSOR_ALREADY_OPEN -6511 ORA-06511 DUP_VAL_ON_INDEX -1 ORA-00001 INVALID_CURSOR -1001 ORA-01001 MISR-MSRS : M1 Support du cours PL/SQL L. KOUTTI
  • 13.
    INVALID_NUMBER -1722 ORA-01722 LOGIN_DENIED -1017 ORA-01717 NO_DATA_FOUND -1403 ORA-01413 NOT_LOGGED_ON -1012 ORA-01012 PROGRAM_ERROR -6501 ORA-06501 STORAGE_ERROR -6500 ORA-06500 TIMEOUT_ON_RESOURCE -51 ORA-00051 TOO_MANY_ROWS -1422 ORA-01422 TRANSACTION_BACKED_OUT -61 ORA-00061 VALUE_ERROR -6502 ORA-06502 ZERO_DIVIDE -1476 ORA-01476 OTHERS : toutes les autres erreurs non explicitement nommées. Pour gérer les exceptions, le développeur doit écrire un gestionnaire des exceptions qui prend le contrôle du déroulement du bloc PL/SQL en présence d'une exception. Le gestionnaire d'exception fait partie du bloc PL/SQL et se trouve après les commandes. Il commence par le mot clé EXCEPTION et se termine avec le même END du bloc. Chaque gestion d'exception consiste à spécifier son nom d'erreur après la clause WHEN et la séquence de la commande à exécuter après le mot clé THEN, comme le montre l'exemple suivant : Les déclencheurs (“triggers”) Les déclencheurs ou ”triggers” sont des séquences d’actions définis par le programmeur qui se déclenchent, sur des actions modifiant les données de la table sur laquelle porte le trigger. Un trigger sera un objet stocké (comme une table ou une procédure). Syntaxe : CREATE [OR REPLACE] TRIGGER <nomTrg> {BEFORE|AFTER} {INSERT|DELETE|UPDATE} ON <nomTable> [FOR EACH ROW [WHEN (<condition>)]] <corps du trigger> Le type d’action qui déclenche le trigger détermine son moment d’exécution : il est précisé au début de l’écriture du code de trigger. (INSERT|DELETE|UPDATE) Le trigger peut être déclenché avant ou après cette action (BEFORE|AFTER) MISR-MSRS : M1 Support du cours PL/SQL L. KOUTTI
  • 14.
    L’option FOR EACHROW [WHEN (<condition>)] fait exécuter le trigger à chaque modification d’une ligne de la table spécifiée (on dit que le trigger est de ”niveau ligne”). En l’absence de cette option, le trigger est exécuté une seule fois (”niveau table”). Caractéristiques • Un déclencheur a un nom. • Il est associé à une table et une seule. • Il peut être actif ou inactif. • Il est opérationnel jusqu’à sa suppression ou la suppression de la table à laquelle il est associé. Référence aux colonnes d’une table • Dans le code associé aux déclencheurs de niveau ligne, on peut accéder aux valeurs des attributs de la ligne modifiée par les variables : :old et :new • Pour un déclencheur sur INSERT, les nouvelles valeurs sont dans :new.<nom attribut> • Pour un déclencheur sur UPDATE, les anciennes valeurs sont dans :old.<nom d’attribut>. Les nouvelles valeurs sont dans :new.<nom d’attribut> • Pour un déclencheur sur DELETE, les anciennes valeurs sont dans :old.<nom d’attribut> Remarques • N’utilisez pas les triggers pour effectuer des contrôles d’intégrité. • Pour éviter de supprimer et recréer un trigger : create or replace trigger • Pour un trigger relatif à plusieurs événements, utiliser les prédicats inserting, updating, deleting if inserting then …end if; if updating then …end if; if deleting then …end if; Activer/désactiver Un trigger est crée par la clause CREATE TRIGGER ou CREATE OR REPLACE TRIGGER. Un trigger existant peut être détruit par DROP TRIGGER. ALTER TRIGGER nomTrigger ENABLE; -- active le trigger ALTER TRIGGER nomTrigger DISABLE; -- désactive le trigger ALTER TABLE nomTable ENABLE ALL TRIGGERS; ALTER TABLE nomTable DISABLE ALL TRIGGERS; MISR-MSRS : M1 Support du cours PL/SQL L. KOUTTI