SlideShare ist ein Scribd-Unternehmen logo
1 von 79
Downloaden Sie, um offline zu lesen
Introduction au PL/SQL Oracle

         Alexandre Mesl´
                       e

          17 octobre 2011
Table des mati`res
              e

1 Notes de cours                                                                                                                                                                  3
  1.1 Introduction au PL/SQL . . . . . . . . . . . . . . . . .       .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    3
      1.1.1 PL/SQL . . . . . . . . . . . . . . . . . . . . . .       .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    3
      1.1.2 Blocs . . . . . . . . . . . . . . . . . . . . . . .      .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    3
      1.1.3 Affichage . . . . . . . . . . . . . . . . . . . . .        .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    3
      1.1.4 Variables . . . . . . . . . . . . . . . . . . . . .      .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    3
      1.1.5 Traitements conditionnels . . . . . . . . . . . .        .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    4
      1.1.6 Traitements r´p´titifs . . . . . . . . . . . . . .
                            e e                                      .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    4
  1.2 Tableaux et structures . . . . . . . . . . . . . . . . . .     .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    5
      1.2.1 Tableaux . . . . . . . . . . . . . . . . . . . . .       .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    5
      1.2.2 Structures . . . . . . . . . . . . . . . . . . . . .     .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    6
  1.3 Utilisation du PL/SQL . . . . . . . . . . . . . . . . . .      .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    8
      1.3.1 Affectation . . . . . . . . . . . . . . . . . . . .       .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    8
      1.3.2 Tables et structures . . . . . . . . . . . . . . .       .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    8
      1.3.3 Transactions . . . . . . . . . . . . . . . . . . .       .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    9
  1.4 Exceptions . . . . . . . . . . . . . . . . . . . . . . . .     .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   10
      1.4.1 Rattraper une exception . . . . . . . . . . . . .        .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   10
      1.4.2 Exceptions pr´d´finies . . . . . . . . . . . . . .
                            e e                                      .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   11
      1.4.3 Codes d’erreur . . . . . . . . . . . . . . . . . .       .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   11
      1.4.4 D´clarer et lancer ses propres exceptions . . . .
                e                                                    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   11
  1.5 Sous-programmes . . . . . . . . . . . . . . . . . . . . .      .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   13
      1.5.1 Proc´dures . . . . . . . . . . . . . . . . . . . .
                    e                                                .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   13
      1.5.2 Fonctions . . . . . . . . . . . . . . . . . . . . .      .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   13
  1.6 Curseurs . . . . . . . . . . . . . . . . . . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   15
      1.6.1 Introduction . . . . . . . . . . . . . . . . . . .       .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   15
      1.6.2 Les curseurs . . . . . . . . . . . . . . . . . . . .     .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   15
  1.7 Curseurs parametr´s . . . . . . . . . . . . . . . . . . .
                          e                                          .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   17
      1.7.1 Introduction . . . . . . . . . . . . . . . . . . .       .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   17
      1.7.2 D´finition . . . . . . . . . . . . . . . . . . . . .
                e                                                    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   17
      1.7.3 D´claration . . . . . . . . . . . . . . . . . . . .
                e                                                    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   17
      1.7.4 Ouverture . . . . . . . . . . . . . . . . . . . . .      .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   17
      1.7.5 Lecture d’une ligne, fermeture . . . . . . . . . .       .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   17
      1.7.6 Boucle pour . . . . . . . . . . . . . . . . . . . .      .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   18
      1.7.7 Exemple r´capitulatif . . . . . . . . . . . . . .
                        e                                            .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   18
  1.8 Triggers . . . . . . . . . . . . . . . . . . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   19
      1.8.1 Principe . . . . . . . . . . . . . . . . . . . . . .     .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   19
      1.8.2 Classification . . . . . . . . . . . . . . . . . . .      .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   19
      1.8.3 Cr´ation . . . . . . . . . . . . . . . . . . . . . .
                 e                                                   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   19
      1.8.4 Acc`s aux lignes en cours de modification . . .
                   e                                                 .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   20
      1.8.5 Contourner le probl`me des tables en mutation
                                   e                                 .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   22
  1.9 Packages . . . . . . . . . . . . . . . . . . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   25
      1.9.1 Principe . . . . . . . . . . . . . . . . . . . . . .     .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   25
      1.9.2 Sp´cification . . . . . . . . . . . . . . . . . . .
                 e                                                   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   25
      1.9.3 Corps . . . . . . . . . . . . . . . . . . . . . . .      .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   25




                                                            1
2 Exercices                                                                                                                                                                                                      27
  2.1 Introduction au PL/SQL .       .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   27
  2.2 Tableaux et Structures . .     .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   28
  2.3 Utilisation PL/SQL . . .       .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   30
  2.4 Exceptions . . . . . . . .     .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   31
  2.5 Sous-programmes . . . . .      .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   32
  2.6 Curseurs . . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   33
  2.7 Curseurs parametr´s . . .
                         e           .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   34
  2.8 Triggers . . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   35
  2.9 Packages . . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   36
  2.10 R´visions . . . . . . . . .
        e                            .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   37

3 Corrig´s
        e                                                                                                                                                                                                        38
  3.1 Introduction au PL/SQL . . . . . . . .                     .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   38
  3.2 Tableaux et Structures . . . . . . . . .                   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   39
  3.3 Application du PL/SQL et Exceptions                        .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   42
  3.4 Sous-programmes . . . . . . . . . . . .                    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   46
  3.5 Curseurs . . . . . . . . . . . . . . . . .                 .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   49
  3.6 Curseurs param´tr´s . . . . . . . . . .
                      e e                                        .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   52
  3.7 Triggers . . . . . . . . . . . . . . . . .                 .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   53
  3.8 Packages . . . . . . . . . . . . . . . . .                 .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   62
  3.9 R´visions . . . . . . . . . . . . . . . .
        e                                                        .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   63

A Scripts de cr´ation de bases
                e                                                                                                                                                                                                67
  A.1 Livraisons Sans contraintes . . . .                .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   67
  A.2 Modules et prerequis . . . . . . . .               .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   68
  A.3 G´om´trie . . . . . . . . . . . . . .
        e e                                              .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   69
  A.4 Livraisons . . . . . . . . . . . . . .             .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   70
  A.5 Arbre g´n´alogique . . . . . . . . .
              e e                                        .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   71
  A.6 Comptes bancaires . . . . . . . . .                .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   72
  A.7 Comptes bancaires avec exceptions                  .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   74
  A.8 Secr´tariat p´dagogique . . . . . .
          e        e                                     .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   76
  A.9 Mariages . . . . . . . . . . . . . . .             .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   78




                                                                                     2
Chapitre 1

Notes de cours

1.1     Introduction au PL/SQL
1.1.1    PL/SQL
    Le PL de PL/SQL signifie Procedural Language. Il s’agit d’une extension proc´durale du SQL permettant d’effectuer
                                                                                  e
des traitements complexes sur une base de donn´es. Les possibilit´s offertes sont les mˆmes qu’avec des langages
                                                   e                   e                     e
imp´ratifs (instructions en s´quence) classiques.
    e                        e
    Ecrivez-le dans un ´diteur dont vous copierez le contenu dans SQL+. Un script ´crit en PL/SQL se termine obliga-
                       e                                                             e
toirement par un /, sinon SQL+ ne l’interpr`te pas. S’il contient des erreurs de compilation, il est possible d’afficher les
                                            e
messages d’erreur avec la commande SQL+ : SHOW ERRORS.

1.1.2    Blocs
   Tout code ´crit dans un langage proc´dural est form´ de blocs. Chaque bloc comprend une section de d´claration
               e                         e               e                                             e
de variables, et un ensemble d’instructions dans lequel les variables d´clar´es sont visibles.
                                                                       e    e
   La syntaxe est
DECLARE
           /∗ d e c l a r a t i o n de v a r i a b l e s ∗/
BEGIN
           /∗ i n s t r u c t i o n s a e x e c u t e r ∗/
END;


1.1.3    Affichage
   Pour afficher le contenu d’une variable, les proc´dures DBMS OUTPUT.PUT() et DBMS OUTPUT.PUT LINE() prennent
                                                   e
en argument une valeur ` afficher ou une variable dont la valeur est ` afficher. Par d´faut, les fonctions d’affichage
                          a                                            a               e
sont desactiv´es. Il convient, ` moins que vous ne vouliez rien voir s’afficher, de les activer avec la commande SQL+
             e                 a
SET SERVEROUTPUT ON.

1.1.4    Variables
   Une variable se d´clare de la sorte :
                    e
nom type [ : = initialisation ] ;

   L’initisation est optionnelle. Nous utiliserons les mˆmes types primitifs que dans les tables. Par exemple :
                                                        e
SET SERVEROUTPUT ON
DECLARE
        c varchar2 ( 1 5 ) := ’ H e l l o World ! ’ ;
BEGIN
        DBMS_OUTPUT . PUT_LINE ( c ) ;
END;
/

   Les affectations se font avec la syntaxe variable := valeur ;


                                                              3
1.1.5       Traitements conditionnels
    Le IF et le CASE fonctionnent de la mˆme fa¸on que dans les autres langages imp´ratifs :
                                         e     c                                   e
IF /∗ c o n d i t i o n 1 ∗/ THEN
         /∗ i n s t r u c t i o n s 1 ∗/
ELSE
         /∗ i n s t r u c t i o n s 2 ∗/
END IF ;

    voire
IF /∗ c o n d i t i o n 1 ∗/ THEN
         /∗ i n s t r u c t i o n s 1 ∗/
ELSIF /∗ c o n d i t i o n 2 ∗/
         /∗ i n s t r u c t i o n s 2 ∗/
ELSE
         /∗ i n s t r u c t i o n s 3 ∗/
END IF ;

    Les conditions sont les mˆmes qu’en SQL. Le switch du langage C s’impl´mente en PL/SQL de la fa¸on suivante :
                             e                                            e                        c
CASE /∗ v a r i a b l e ∗/
W E /∗ v a l e u r 1 ∗/ THEN
  HN
        /∗ i n s t r u c t i o n s 1 ∗/
W E /∗ v a l e u r 2 ∗/ THEN
  HN
        /∗ i n s t r u c t i o n s 2 ∗/
 ...
W E /∗ v a l e u r n ∗/ THEN
  HN
        /∗ i n s t r u c t i o n s n ∗/
ELSE
        /∗ i n s t r u c t i o n s par d ´ f a u t ∗/
                                         e
END CASE;


1.1.6       Traitements r´p´titifs
                         e e
    LOOP ... END LOOP ; permet d’impl´menter les boucles
                                     e
LOOP
         /∗ i n s t r u c t i o n s ∗/
END LOOP ;

    L’instruction EXIT WHEN permet de quitter une boucle.
LOOP
         /∗ i n s t r u c t i o n s ∗/
         EXIT W E /∗ c o n d i t i o n ∗/ ;
                  HN
END LOOP ;

    La boucle FOR existe aussi en PL/SQL :
FOR /∗ v a r i a b l e ∗/ IN /∗ i n f ∗/ . . /∗ sup ∗/ LOOP
         /∗ i n s t r u c t i o n s ∗/
END LOOP ;

    Ainsi que la boucle WHILE :
WHILE /∗ c o n d i t i o n ∗/ LOOP
         /∗ i n s t r u c t i o n s ∗/
END LOOP ;

    Est-il possible, en bidouillant, d’impl´menter une boucle DO ... WHILE ?
                                           e




                                                          4
1.2     Tableaux et structures
1.2.1    Tableaux
Cr´ation d’un type tableau
  e
   Les types tableau doivent ˆtre d´finis explicitement par une d´claration de la forme
                             e     e                            e
TYPE /∗ t y p e ∗/ IS VARRAY ( /∗ t a i l l e ∗/ ) OF /∗ t y p e E l e m e n t s ∗/ ;

   – type est le nom du type tableau cr´e par cette instruction
                                       e
   – taille est le nombre maximal d’´l´ments qu’il est possible de placer dans le tableau.
                                     ee
   – typeElements est le type des ´l´ments qui vont ˆtre stock´s dans le tableau, il peut s’agir de n’importe quel
                                   ee                 e          e
     type.
   Par exemple, cr´ons un type tableau de nombres indic´ de 1 ` 10, que nous appelerons numberTab
                  e                                      e      a
TYPE numberTab IS VARRAY ( 1 0 ) OF N M E
                                     U B R;


D´claration d’un tableau
 e
   Dor´navant, le type d’un tableau peut ˆtre utilis´ au mˆme titre que NUMBER ou VARCHAR2. Par exemple, d´clarons
       e                                 e          e     e                                               e
un tableau appel´ t de type numberTab,
                e
DECLARE
           TYPE numberTab IS VARRAY ( 1 0 ) OF N M E
                                                U B R;
           t numberTab ;
BEGIN
           /∗ i n s t r u c t i o n s ∗/
END;
/


Allocation d’un tableau
    La cr´ation d’un type tableau met ` disposition un constructeur du mˆme nom que le type cr´´. Cette fonction
         e                             a                                  e                          ee
r´serve de l’espace m´moire pour ce tableau et retourne l’adresse m´moire de la zone r´serv´e, il s’agit d’une sorte de
 e                   e                                             e                  e    e
malloc. Si, par exemple, un type tableau numtab a ´t´ cr´e, la fonction numtab() retourne une tableau vide.
                                                    ee e
DECLARE
           TYPE numberTab IS VARRAY ( 1 0 ) OF N M E
                                                U B R;
           t numberTab ;
BEGIN
           t := numberTab ( ) ;
           /∗ u t i l i s a t i o n du t a b l e a u ∗/
END;
/

   Une fois cette allocation faite, il devient presque possible d’utiliser le tableau...

Dimensionnement d’un tableau
   Le tableau retourn´ par le constructeur est vide. Il convient ensuite de r´server de l’espace pour stocker les ´l´ments
                      e                                                      e                                    ee
qu’il va contenir. On utilise pour cela la m´thode EXTEND(). EXTEND s’invoque en utilisant la notation point´e. Par
                                            e                                                                       e
exemple,
DECLARE
           TYPE numberTab IS VARRAY ( 1 0 ) OF N M E
                                                U B R;
           t numberTab ;
BEGIN
           t := numberTab ( ) ;
           t . EXTEND ( 4 ) ;
           /∗ u t i l i s a t i o n du t a b l e a u ∗/
END;
/


                                                             5
Dans cet exemple, t.EXTEND(4) ; permet par la suite d’utiliser les ´l´ments du tableau t(1), t(2), t(3) et t(4).
                                                                         ee
Il n’est pas possible ”d’´tendre” un tableau ` une taille sup´rieure ` celle sp´cifi´e lors de la cr´ation du type tableau
                         e                   a               e       a         e e                 e
associ´.
       e

Utilisation d’un tableau
   On acc`de, en lecture et en ´criture, au i-`me ´l´ment d’une variable tabulaire nomm´ T avec l’instruction T(i).
          e                     e             e   ee                                    e
Les ´l´ments sont indic´s ` partir de 1.
    ee                 e a
   Effectuons, par exemple, une permutation circulaire vers la droite des ´l´ments du tableau t.
                                                                         ee
DECLARE
           TYPE numberTab IS VARRAY ( 1 0 ) OF N M E
                                                U B R;
           t numberTab ;
           i number ;
           k number ;
BEGIN
          t := numberTab ( ) ;
          t . EXTEND ( 1 0 ) ;
          FOR i IN 1 . . 1 0 LOOP
                     t ( i ) := i ;
          END LOOP ;
          k := t ( 1 0 ) ;
          FOR i in REVERSE 2 . . 1 0 LOOP
                     t ( i ) := t ( i − 1 ) ;
          END LOOP ;
          t ( 1 ) := k ;
          FOR i IN 1 . . 1 0 LOOP
                     DBMS_OUTPUT . PUT_LINE ( t ( i ) ) ;
          END LOOP ;
END;
/


1.2.2    Structures
    Un structure est un type regroupant plusieurs types. Une variable de type structur´ contient plusieurs variables,
                                                                                      e
ces variables s’appellent aussi des champs.

Cr´ation d’un type structur´
  e                        e
   On d´finit un type structur´ de la sorte :
       e                     e
TYPE /∗ nomType ∗/ IS RECORD
(
        /∗ l i s t e d e s champs ∗/
);

    nomType est le nom du type structur´ construit avec la syntaxe pr´c´dente. La liste suit la mˆme syntaxe que la
                                         e                           e e                         e
liste des colonnes d’une table dans un CREATE TABLE. Par exemple, construisons le type point (dans IR2 ),
TYPE point IS RECORD
(
        abscisse N M E ,
                  U BR
        ordonnee N M E
                  U BR
);

    Notez bien que les types servant ` d´finir un type structur´ peuvent ˆtre quelconques : variables scalaires, tableaux,
                                     a e                      e         e
structures, etc.

D´claration d’une variable de type structur´
 e                                         e
   point est maintenant un type, il devient donc possible de cr´er des variables de type point, la r`gle est toujours la
                                                               e                                    e
mˆme pour d´clarer des variables en PL/SQL, par exemple
 e          e


                                                           6
p point ;

   permet de d´clarer une variable p de type point.
              e

Utilisation d’une variable de type structur´
                                           e
   Pour acc´der ` un champ d’une variable de type structur´, en lecture ou en ´criture, on utilise la notation point´e :
             e  a                                           e                 e                                     e
v.c est le champ appel´ c de la variable structur´ appel´e v. Par exemple,
                      e                          e      e
DECLARE
            TYPE point IS RECORD
            (
            abscisse N M E ,
                      U BR
            ordonnee N M E
                      U BR
            );
            p point ;
BEGIN
            p . abscisse := 1 ;
            p . ordonnee := 3 ;
            DBMS_OUTPUT . PUT_LINE ( ’ p . a b s c i s s e = ’ | | p . abscisse | |
                      ’ and p . ordonnee = ’ | | p . ordonnee ) ;
END;
/

    Le script ci-dessous cr´e le type point, puis cr´e une variable t de type point, et enfin affecte aux champs abscisse
                           e                        e
et ordonnee du point p les valeurs 1 et 3.




                                                           7
1.3     Utilisation du PL/SQL
   Ce cours est une introduction aux interactions possibles entre la base de donn´es et les scripts PL/SQL.
                                                                                 e

1.3.1    Affectation
   On place dans une variable le r´sultat d’une requˆte en utilisant le mot-cl´ INTO. Les instructions
                                  e                 e                         e
SELECT champ_1 , . . . , champ_n INTO v_1 , . . . , v_n
F O ...
 R M

   affecte aux variables v 1, ..., v n les valeurs retourn´es par la requˆte. Par exemple
                                                         e              e
DECLARE
           num N M E
                U B R;
           nom V R H R 3 0 ) := ’ Poup´ e Batman ’ ;
                A C A 2(              e
BEGIN
          SELECT numprod INTO num
                  F O PRODUIT
                   R M
                  W E E nomprod = nom ;
                    HR
          DBMS_OUTPUT . PUT_LINE ( ’L ’ ’ a r t i c l e ’ | |
                  nom | | ’ a pour num´ro ’ | | num ) ;
                                              e
END;
/

    Prˆtez attention au fait que la requˆte doit retourner une et une une seule ligne, sinon, une erreur se produit `
      e                                 e                                                                           a
l’ex´cution.
    e

1.3.2    Tables et structures
    Si vous ne tenez pas ` vous prendre la tˆte pour choisir le type de chaque variable, demandez-vous ce que vous
                          a                  e
allez mettre dedans ! Si vous tenez ` y mettre une valeur qui se trouve dans une colonne d’une table, il est possible de
                                    a
vous r´f´rer directement au type de cette colonne avec le type nomTable.nomColonne%type. Par exemple,
       ee
DECLARE
           num PRODUIT . numprod%type ;
           nom PRODUIT . nomprod%type := ’ Poup´ e Batman ’ ;
                                               e
BEGIN
          SELECT numprod INTO num
                  F O PRODUIT
                   R M
                  W E E nomprod = nom ;
                    HR
          DBMS_OUTPUT . PUT_LINE ( ’L ’ ’ a r t i c l e ’ | |
                  nom | | ’ a pour num´ro ’ | | num ) ;
                                              e
END;
/

   Pour aller plus loin, il est mˆme possible de d´clarer une structure pour repr´senter une ligne d’une table, le type
                                 e                e                              e
porte alors le nom suivant : nomTable%rowtype.
DECLARE
           nom PRODUIT . nomprod%type := ’ Poup´ e Batman ’ ;
                                               e
           ligne PRODUIT%rowtype ;
BEGIN
          SELECT ∗ INTO ligne
                  F O PRODUIT
                   R M
                  W E E nomprod = nom ;
                    HR
          DBMS_OUTPUT . PUT_LINE ( ’L ’ ’ a r t i c l e ’ | |
                  ligne . nomprod | | ’ a pour num´ro ’ | | ligne . numprod ) ;
                                                              e
END;
/




                                                           8
1.3.3     Transactions
    Un des m´canismes les plus puissants des SGBD r´cents r´side dans le syst`me des transactions. Une transaction
               e                                        e      e                 e
est un ensemble d’op´rations “atomiques”, c’est-`-dire indivisible. Nous consid´rerons qu’un ensemble d’op´rations est
                     e                            a                            e                           e
indivisible si une ex´cution partielle de ces instructions poserait des probl`mes d’int´grit´ dans la base de donn´es.
                     e                                                       e         e    e                     e
Par exemple, dans le cas d’une base de donn´es de gestion de comptes en banque, un virement d’un compte ` un autre
                                             e                                                               a
se fait en deux temps : cr´diter un compte d’une somme s, et d´biter un autre de la mˆme somme s. Si une erreur
                            e                                      e                      e
survient pendant la deuxi`me op´ration, et que la transaction est interrompue, le virement est incomplet et le patron
                           e     e
va vous assassiner.

Il convient donc de disposer d’un m´canisme permettant de se prot´ger de ce genre de d´sagr´ment. Plutˆt que
                                         e                               e                     e    e            o
se casser la tˆte ` tester les erreurs ` chaque ´tape et ` balancer des instructions permettant de “revenir en arri`re”,
              e a                      a        e        a                                                         e
nous allons utiliser les instructions COMMIT et ROLLBACK.

Voici le squelette d’un exemple :
/∗ i n s t r u c t i o n s ∗/
IF /∗ e r r e u r ∗/ THEN
            ROLLBACK;
ELSE
            C M I
              O MT;
END;

   Le ROLLBACK annule toutes les modifications faites depuis le d´but de la transaction (donc depuis le pr´c´dent
                                                                 e                                       e e
COMMIT), COMMIT les enregistre d´finitivement dans la base de donn´es.
                                e                                e

La variable d’environnement AUTOCOMMIT, qui peut ˆtre positionn´e ` ON ou ` OFF permet d’activer la gestion des
                                                      e             e a         a
transactions. Si elle est positionn´e ` ON, chaque instruction a des r´percussions imm´diates dans la base, sinon, les
                                   e a                                e               e
modifications ne sont effectives qu’une fois qu’un COMMIT a ´t´ ex´cut´.
                                                             ee e e




                                                           9
1.4      Exceptions
    Le m´canisme des exceptions est impl´ment´ dans la plupart des langages r´cent, notament orient´s objet. Cette
         e                                  e      e                              e                      e
fa¸on de programmer a quelques avantages imm´diats :
  c                                               e
    – obliger les programmeurs ` traiter les erreurs : combien de fois votre prof de C a hurl´ en vous suppliant
                                     a                                                              e
      de v´rifier les valeurs retourn´es par un malloc, ou un fopen ? La plupart des compilateurs des langages `
           e                         e                                                                                 a
      exceptions (notamment java) ne compilent que si pour chaque erreur potentielle, vous avez pr´par´ un bloc de
                                                                                                       e e
      code (´ventuellement vide...) pour la traiter. Le but est de vous assurer que vous n’avez pas oubli´ d’erreur.
             e                                                                                            e
    – Rattraper les erreurs en cours d’ex´cution : Si vous programmez un syst`me de s´curit´ de centrale
                                                  e                                        e        e      e
      nucl´aire ou un pilote automatique pour l’aviation civile, une erreur de m´moire qui vous afficherait l’´cran
           e                                                                        e                             e
      bleu de windows, ou le message “Envoyer le rapport d’erreur ?”, ou plus simplement le fameux “Segmentation
      fault” produirait un effet des plus mauvais. Certaines erreurs d’´xecution sont rattrapables, autrement dit, il est
                                                                       e
      possible de r´soudre le probl`me sans interrompre le programme.
                   e               e
    – Ecrire le traitement des erreurs ` part : Pour des raisons fiabilit´, de lisibilit´, il a ´t´ consid´r´ que
                                              a                                   e           e       ee        ee
      m´langer le code “normal” et le traitement des erreurs ´tait un style de programmation perfectible... Dans les
        e                                                       e
      langages ` exception, les erreurs sont trait´es ` part.
               a                                  e a

1.4.1     Rattraper une exception
    Je vous ai menti dans le premier cours, un bloc en PL/SQL a la forme suivante :
DECLARE
            /∗ d e c l a r a t i o n s ∗/
BEGIN
        /∗ i n s t r u c t i o n s ∗/
EXCEPTION
        /∗ t r a i t e m e n t d e s e r r e u r s ∗/
END;

   Une exception est une “erreur type”, elle porte un nom, au mˆme titre qu’une variable a une identificateur, par
                                                                 e
exemple GLUBARF. Lorsque dans les instructions, l’erreur GLUBARF se produit, le code du BEGIN s’interrompt et le
code de la section EXCEPTION est lanc´. On dit aussi que quand une exception est lev´e (raised) (on dit aussi jet´e
                                     e                                              e                            e
(thrown)), on la rattrape (catch) dans le bloc EXCEPTION. La section EXCEPTION a la forme suivante :
EXCEPTION
        W E E1 THEN
         HN
               /∗ t r a i t e m e n t       ∗/
        W E E2 THEN
         HN
               /∗ t r a i t e m e n t       ∗/
        W E E3 THEN
         HN
               /∗ t r a i t e m e n t       ∗/
        W E OTHERS THEN
         HN
               /∗ t r a i t e m e n t       ∗/
END;

    On ´num`re les erreurs les plus pertinentes en utilisant leur nom et en consacrant ` chacune d’elle un traitement
       e     e                                                                         a
particulier pour rattraper (ou propager) l’erreur. Quand un bloc est trait´, les WHEN suivants ne sont pas ´valu´s.
                                                                            e                                 e    e
OTHERS est l’exception par d´faut, OTHERS est toujours v´rifi´, sauf si un cas pr´c´dent a ´t´ v´rifi´. Dans l’exemple
                             e                            e e                    e e       ee e e
suivant :
DECLARE
            /∗ d e c l a r a t i o n s ∗/
BEGIN
        /∗ i n s t r u c t i o n s ∗/
        C M I
         O MT;
EXCEPTION
        W E GLUBARF THEN
         HN
                    ROLLBACK;
                     DBMS_OUTPUT . PUT_LINE ( ’GLUBARF e x c e p t i o n r a i s e d ! ’ ) ;
        W E OTHERS THEN
         HN
                     DBMS_OUTPUT . PUT_LINE ( ’SQLCODE = ’ | | SQLCODE ) ;
                     DBMS_OUTPUT . PUT_LINE ( ’SQLERRM = ’ | | SQLERRM ) ;


                                                          10
END;

    Les deux variables globales SQLCODE et SQLERRM contiennent respectivement le code d’erreur Oracle et un message
d’erreur correspondant ` la derni`re exception lev´e. Chaque exception a donc, en plus d’un nom, un code et un
                         a         e              e
message.

1.4.2    Exceptions pr´d´finies
                      e e
   Bon nombre d’exceptions sont pr´d´finies par Oracle, par exemple
                                   e e
   – NO DATA FOUND est lev´e quand la requˆte d’une instruction de la forme SELECT ... INTO ... ne retourne
                            e                e
     aucune ligne
   – TOO MANY ROWS est lev´e quand la requˆte d’une instruction de la forme SELECT ... INTO ... retourne plusieurs
                           e              e
     lignes
   – DUP VAL ON INDEX est lev´e si une insertion (ou une modification) est refus´e ` cause d’une contrainte d’unicit´.
                              e                                                 e a                                e
   On peut enrichir notre exemple de la sorte :
DECLARE
           num N M E
                U B R;
           nom V R H R 3 0 ) := ’ Poup´ e Batman ’ ;
                A C A 2(              e
BEGIN
        SELECT numprod INTO num
                F O PRODUIT
                 R M
                W E E nomprod = nom ;
                   HR
        DBMS_OUTPUT . PUT_LINE ( ’L ’ ’ a r t i c l e ’ | |
                nom | | ’ a pour num´ro ’ | | num ) ;
                                            e
EXCEPTION
        W E NO_DATA_FOUND THEN
         HN
                DBMS_OUTPUT . PUT_LINE ( ’ Aucun a r t i c l e ne p o r t e l e nom ’
                 | | nom ) ;
        W E TOO_MANY_ROWS THEN
         HN
                DBMS_OUTPUT . PUT_LINE ( ’ P l u s i e u r s a r t i c l e s p o r t e n t l e nom ’
                 | | nom ) ;
        W E OTHERS THEN
         HN
                DBMS_OUTPUT . PUT_LINE ( ’ I l y a un g r o s p r o b l` m e . . . ’ ) ;
                                                                             e
END;
/

   SELECT numprod INTO num... l`ve une exception si la requˆte renvoie un nombre de lignes diff´rent de 1.
                               e                           e                                  e

1.4.3    Codes d’erreur
   Je vous encore menti, certaines exceptions n’ont pas de nom. Elle ont seulement un code d’erreur, il est conseill´
                                                                                                                    e
de se reporter ` la documentation pour les obtenir. On les traite de la fa¸on suivante
               a                                                          c
EXCEPTION
        W E OTHERS THEN
         HN
               IF SQLCODE = CODE1 THEN
                       /∗ t r a i t e m e n t ∗/
               ELSIF SQLCODE = CODE2 THEN
                       /∗ t r a i t e m e n t ∗/
               ELSE
                       DBMS_OUTPUT . PUT_LINE ( ’ J ’ ’ v o i s pas c ’ ’ que ca
                       peut et re . . . ’ ) ;
END;

   C’est souvent le cas lors de violation de contraintes.

1.4.4    D´clarer et lancer ses propres exceptions
          e
    Exception est un type, on d´clare donc les exceptions dans une section DECLARE. Une exception se lance avec
                               e
l’instruction RAISE. Par exemple,


                                                            11
DECLARE
           GLUBARF EXCEPTION;
BEGIN
        RAISE GLUBARF ;
EXCEPTION
        W E GLUBARF THEN
         HN
                DBMS_OUTPUT . PUT_LINE ( ’ g l u b a r f r a i s e d . ’ ) ;
END;
/




                                                         12
1.5     Sous-programmes
1.5.1     Proc´dures
              e
Syntaxe
   On d´finit une proc´dure de la sorte
       e             e
CREATE OR REPLACE PROCEDURE /∗ nom ∗/ ( /∗ p a r a m e t r e s ∗/ ) IS
        /∗ d e c l a r a t i o n d e s v a r i a b l e s l o c a l e s ∗/
BEGIN
        /∗ i n s t r u c t i o n s ∗/
END;

   les param`tres sont une simple liste de couples nom type. Par exemple, la procedure suivante affiche un compte `
            e                                                                                                   a
rebours.
CREATE OR REPLACE PROCEDURE compteARebours ( n N M E
                                                U B R) IS
BEGIN
        IF n >= 0 THEN
                 DBMS_OUTPUT . PUT_LINE ( n ) ;
                 compteARebours ( n − 1 ) ;
        END IF ;
END;


Invocation
   En PL/SQL, une proc´dure s’invoque tout simplement avec son nom. Mais sous SQL+, on doit utiliser le mot-cl´
                        e                                                                                     e
CALL. Par exemple, on invoque le compte ` rebours sous SQL+ avec la commande CALL compteARebours(20).
                                        a

Passage de param`tres
                e
   Oracle permet le passage de param`tres par r´f´rence. Il existe trois types de passage de param`tres :
                                      e          ee                                               e
   – IN : passage par valeur
   – OUT : aucune valeur pass´e, sert de valeur de retour
                              e
   – IN OUT : passage de param`tre par r´f´rence
                                e         ee
   Par d´faut, le passage de param`tre se fait de type IN.
        e                          e
CREATE OR REPLACE PROCEDURE incr ( val IN OUT N M E
                                               U B R) IS
BEGIN
        val := val + 1 ;
END;


1.5.2     Fonctions
Syntaxe
   On cr´e une nouvelle fonction de la fa¸on suivante :
        e                                c
CREATE OR REPLACE FUNCTION /∗ nom ∗/ ( /∗ p a r a m e t r e s ∗/ ) RETURN /∗ t y p e
∗/ IS
        /∗ d e c l a r a t i o n d e s v a r i a b l e s l o c a l e s ∗/
BEGIN
        /∗ i n s t r u c t i o n s ∗/
END;

   L’instruction RETURN sert ` retourner une valeur. Par exemple,
                             a
CREATE OR REPLACE FUNCTION module ( a N M E , b N M E
                                       U BR      U B R) RETURN N M E IS
                                                                U BR
BEGIN
        IF a < b THEN
                RETURN a ;
        ELSE


                                                          13
RETURN module ( a − b , b ) ;
          END IF ;
END;


Invocation
    Tout comme les proc´dures, l’invocation des fonctions ne pose aucun probl`me en PL/SQL, par contre, sous SQL+,
                         e                                                   e
c’est quelque peu particulier. On passe par une pseudo-table nomm´e DUAL de la fa¸on suivante :
                                                                   e             c
SELECT module ( 2 1 , 1 2 ) F O DUAL ;
                             R M


Passage de param`tres
                e
   Les param`tres sont toujours pass´s avec le type IN.
            e                       e




                                                          14
1.6     Curseurs
1.6.1    Introduction
    Les instructions de type SELECT ... INTO ... manquent de souplesse, elles ne fontionnent que sur des requˆtes  e
retourant une et une seule valeur. Ne serait-il pas int´ressant de pouvoir placer dans des variables le r´sultat d’une
                                                       e                                                 e
requˆte retournant plusieurs lignes ? A m´diter...
     e                                   e

1.6.2    Les curseurs
   Un curseur est un objet contenant le r´sultat d’une requˆte (0, 1 ou plusieurs lignes).
                                         e                 e

d´claration
 e
   Un curseur se d´clare dans une section DECLARE :
                  e
CURSOR /∗ nomcurseur ∗/ IS /∗ r e q u ˆ t e ∗/ ;
                                      e

   Par exemple, si on tient ` r´cup´rer tous les employ´s de la table EMP, on d´clare le curseur suivant.
                            a e    e                   e                       e
CURSOR emp_cur IS
        SELECT ∗ F O EMP ;
                  R M


Ouverture
    Lors de l’ouverture d’un curseur, la requˆte du curseur est ´valu´e, et le curseur contient toutes les donn´es
                                             e                   e   e                                         e
retourn´es par la requˆte. On ouvre un curseur dans une section BEGIN :
        e             e
OPEN /∗ nomcurseur ∗/ ;

   Par exemmple,
DECLARE
           CURSOR emp_cur IS
                   SELECT ∗ F O EMP ;
                             R M
BEGIN
           OPEN emp_cur ;
           /∗ U t i l i s a t i o n du c u r s e u r ∗/
END;


Lecture d’une ligne
    Une fois ouvert, le curseur contient toutes les lignes du r´sultat de la requˆte On les r´cup`re une par une en
                                                               e                 e           e   e
utilisant le mot-cl´ FETCH :
                   e
FETCH /∗ nom curseur             ∗/ INTO /∗ l i s t e v a r i a b l e s ∗/ ;

   La liste de variables peut ˆtre remplac´e par une structure de type nom curseur%ROWTYPE. Si la lecture de la ligne
                              e             e
´choue, parce qu’il n’y a plus de ligne ` lire, l’attribut %NOTFOUND prend la valeur vrai.
e                                       a
DECLARE
           CURSOR emp_cur IS
                   SELECT ∗ F O EMP ;
                             R M
           ligne emp_cur%rowtype
BEGIN
          OPEN emp_cur ;
          LOOP
                    FETCH emp_cur INTO ligne ;
                    EXIT W E emp_cur%NOTFOUND ;
                          HN
                    DBMS_OUTPUT . PUT_LINE ( ligne . ename ) ;
          END LOOP ;
          /∗ . . . ∗/
END;



                                                             15
Fermeture
  Apr`s utilisation, il convient de fermer le curseur.
     e
CLOSE /∗ nomcurseur ∗/ ;

  Compl´tons notre exemple,
       e
DECLARE
          CURSOR emp_cur IS
                  SELECT ∗ F O EMP ;
                            R M
          ligne emp_cur%rowtype ;
BEGIN
          OPEN emp_cur ;
          LOOP
                   FETCH emp_cur INTO ligne ;
                   EXIT W E emp_cur%NOTFOUND ;
                          HN
                   DBMS_OUTPUT . PUT_LINE ( ligne . ename ) ;
          END LOOP ;
          CLOSE emp_cur ;
END;
/

  Le programme ci-dessus peut aussi s’´crire
                                      e
DECLARE
          CURSOR emp_cur IS
                  SELECT ∗ F O EMP ;
                            R M
          ligne emp_cur%rowtype ;
BEGIN
          OPEN emp_cur ;
          FETCH emp_cur INTO ligne ;
          WHILE emp_cur%FOUND LOOP
                   DBMS_OUTPUT . PUT_LINE ( ligne . ename ) ;
                   FETCH emp_cur INTO ligne ;
          END LOOP ;
          CLOSE emp_cur ;
END;


Boucle FOR
  Il existe une boucle FOR se chargeant de l’ouverture, de la lecture des lignes du curseur et de sa fermeture,
FOR ligne IN emp_cur LOOP
         /∗ Traitement ∗/
END LOOP ;

  Par exemple,
DECLARE
          CURSOR emp_cur IS
                  SELECT ∗ F O EMP ;
                            R M
          ligne emp_cur%rowtype ;
BEGIN
          FOR ligne IN emp_cur LOOP
                   DBMS_OUTPUT . PUT_LINE ( ligne . ename ) ;
          END LOOP ;
END;
/




                                                         16
1.7     Curseurs parametr´s
                         e
1.7.1    Introduction
   A votre avis, le code suivant est-il valide ?
DECLARE
          N M E n := 1 4 ;
           U BR
BEGIN
           DECLARE
                      CURSOR C IS
                              SELECT ∗
                              F O PERSONNE
                               R M
                              W E E numpers >= n ;
                                HR
                      ROW C%rowType ;
           BEGIN
                      FOR ROW IN C LOOP
                              DBMS_OUTPUT . PUT_LINE ( ROW . numpers ) ;

                      END LOOP ;
          END;
END;
/

   R´ponse : non. La requˆte d’un curseur ne peut pas contenir de variables dont les valeurs ne sont pas fix´es.
     e                      e                                                                                      e
Pourquoi ? Parce que les valeurs des ces sont susceptibles de changer entre la d´claration du curseur et son ouverture.
                                                                                e
Le rem`de est un curseur param´tr´.
       e                        e e

1.7.2    D´finition
          e
    Un curseur param´tr´ est un curseur dont la requˆte contient des variables dont les valeurs ne seront fix´es qu’`
                    e e                             e                                                       e      a
l’ouverture.

1.7.3    D´claration
          e
   On pr´cise la liste des noms et des type des param`tres entre parenth`ses apr`s le nom du curseur :
        e                                            e                  e       e
  CURSOR /∗ nom ∗/ ( /∗ l i s t e d e s p a r a m` t r e s ∗/ ) IS
                                                 e
        /∗ r e q u ˆ t e ∗/
                   e

   Par exemple, cr´eons une requˆte qui, pour une personne donn´e, nous donne la liste des noms et pr´noms de ses
                  e             e                              e                                     e
enfants :
  CURSOR enfants ( numparent N M E
                              U B R) IS
        SELECT ∗
        F O PERSONNE
         R M
        W E E pere = numparent
          HR
        OR mere = numparent ;


1.7.4    Ouverture
   On ouvre un curseur param´tr´ en passant en param`tre les valeurs des variables :
                            e e                     e
  OPEN /∗ nom ∗/ ( /∗ l i s t e d e s p a r a m` t r e s ∗/ )
                                               e

   Par exemple,
  OPEN enfants ( 1 ) ;


1.7.5    Lecture d’une ligne, fermeture
   la lecture d’une ligne suit les mˆmes r`gles qu’avec un curseur non param´tr´.
                                    e     e                                 e e


                                                          17
1.7.6   Boucle pour
  La boucle pour se charge de l’ouverture, il convient donc de placer les param`tre dans l’entˆte de la boucle,
                                                                               e              e
 FOR /∗ v a r i a b l e ∗/ IN /∗ nom ∗/ ( /∗ l i s t e p a r a m` t r e s ∗/ ) LOOP
                                                                e
       /∗ i n s t r u c t i o n s ∗/
 END LOOP ;

  Par exemple,
 FOR e IN enfants ( 1 ) LOOP
       DBMS_OUTPUT . PUT_LINE ( e . nompers | |          ’ ’ | | e . prenompers ) ;
 END LOOP ;


1.7.7   Exemple r´capitulatif
                 e

DECLARE
          CURSOR parent IS
                  SELECT ∗
                  F O PERSONNE ;
                   R M
          p parent%rowtype ;
          CURSOR enfants ( numparent N M E
                                      U B R) IS
                  SELECT ∗
                  F O PERSONNE
                   R M
                  W E E pere = numparent
                    HR
                  OR mere = numparent ;
          e enfants%rowtype ;
BEGIN
          FOR p IN parent LOOP
                   DBMS_OUTPUT . PUT_LINE ( ’ Les e n f a n t s de ’ | | p . prenom | |
                           ’ ’ | | p . nom | | ’ s o n t : ’ ) ;
                   FOR e IN enfants ( p . numpers ) LOOP
                           DBMS_OUTPUT . PUT_LINE ( ’ ∗ ’ | | e . prenom
                                     | | ’ ’ | | e . nom         );
                  END LOOP ;
          END LOOP ;
END;
/




                                                        18
1.8      Triggers
1.8.1     Principe
   Un trigger est une proc´dure stock´e qui se lance automatiquement lorsqu’un ´v´nement se produit. Par ´v´nement,
                          e           e                                          e e                     e e
on entend dans ce cours toute modification des donn´es se trouvant dans les tables. On s’en sert pour contrˆler ou
                                                       e                                                     o
appliquer des contraintes qu’il est impossible de formuler de fa¸on d´clarative.
                                                                c    e

1.8.2     Classification
Type d’´v´nement
       e e
   Lors de la cr´ation d’un trigger, il convient de pr´ciser quel est le type d’´v´nement qui le d´clenche. Nous r´aliserons
                e                                     e                         e e               e               e
dans ce cours des triggers pour les ´v´nements suivants :
                                     e e
   – INSERT
   – DELETE
   – UPDATE

Moment de l’´xecution
            e
   On pr´cise aussi si le trigger doit ˆtre ´xecut´ avant (BEFORE) ou apr`s (AFTER) l’´v´nement.
        e                              e    e     e                      e            e e

Ev´nements non atomiques
  e
    Lors que l’on fait un DELETE ..., il y a une seule instruction, mais plusieurs lignes sont affect´es. Le trigger doit-il
                                                                                                    e
ˆtre ex´cut´ pour chaque ligne affect´e (FOR EACH ROW), ou seulement une fois pour toute l’instruction (STATEMENT) ?
e      e e                          e
    – un FOR EACH ROW TRIGGER est ex´cut´ ` chaque fois qu’une ligne est affect´e.
                                         e ea                                        e
    – un STATEMENT TRIGGER est ´xecut´e ` chaque fois qu’une instruction est lanc´e.
                                  e       e a                                          e

1.8.3     Cr´ation
            e
Syntaxe
   On d´clare un trigger avec l’instruction suivante :
       e
CREATE OR REPLACE TRIGGER nomtrigger
 [ BEFORE | AFTER ] [INSERT | DELETE | UPDATE] ON nomtable
 [ FOR EACH ROW | ]
DECLARE
          /∗ d e c l a r a t i o n s ∗/
BEGIN
          /∗ i n s t r u c t i o n s ∗/
END;

   Par exemple,
SQL>    CREATE OR REPLACE TRIGGER pasDeDeleteDansClient
  2     BEFORE DELETE ON CLIENT
  3     BEGIN
  4       RAISE_APPLICATION_ERROR ( −20555 , ’Va t e f a i r e . . . ’ ) ;
  5     END;
  6     /

D´ clencheur cr´ ´ .
 e             ee

SQL> SELECT C U T( ∗ )
             O N
  2 F O CLIENT ;
      R M

  C U T( ∗ )
   O N
−−−−−−−−−−
         21

SQL> DELETE F O CLIENT ;
             R M


                                                            19
DELETE F O CLIENT
        R M
              ∗
ERREUR ` la ligne 1 :
        a
ORA −20555: Va te faire . . .
ORA −06512: ` ”SCOTT.PASDEDELETEDANSCLIENT” , ligne 2
            a
ORA −04088: erreur lors d ex´ cution du d´ clencheur ’SCOTT.PASDEDELETEDANSCLIENT ’
                              e          e


SQL> SELECT C U T( ∗ )
             O N
  2 F O CLIENT ;
      R M

  C U T( ∗ )
   O N
−−−−−−−−−−
         21

   L’instruction RAISE APPLICATION ERROR(code, message) l`ve une exception sans nom portant un code code et
                                                                e
un message d’erreur message. Vous remarquez que comme l’erreur a ´t´ lev´e avant la suppression, les donn´es sont
                                                                       ee     e                                  e
toujours pr´sentes dans la table CLIENT. Le trigger a contrˆl´ une r`gle, et comme elle n’´tait pas respect´e, il a lanc´
            e                                              oe       e                     e                e            e
une erreur.

Combinaisons d’´v´nements
               e e
    Il est possible, en s´parant les types d’´v´nement par le mot-cl´ OR, de d´finir un trigger d´clench´ par plusieurs
                         e                   e e                    e         e                 e      e
´v´nements. Les variables bool´ennes INSERTING, UPDATING et DELETING permettent d’identifier l’´v´nement qui a
e e                              e                                                                   e e
d´clench´ le trigger.
 e        e
CREATE OR REPLACE TRIGGER afficheEvenement
BEFORE INSERT OR UPDATE OR DELETE ON CLIENT
FOR EACH ROW
BEGIN
         IF INSERTING THEN
                 DBMS_OUTPUT . PUT_LINE ( ’ I n s e r t i o n dans CLIENT ’ ) ;
         ELSIF UPDATING THEN
                 DBMS_OUTPUT . PUT_LINE ( ’ Mise a j o u r dans CLIENT ’ ) ;
        ELSE
                 DBMS_OUTPUT . PUT_LINE ( ’ S u p p r e s s i o n dans CLIENT ’ ) ;
        END IF ;
END;


1.8.4    Acc`s aux lignes en cours de modification
            e
   Dans les FOR EACH ROW triggers, il est possible avant la modification de chaque ligne, de lire l’ancienne ligne et la
nouvelle ligne par l’interm´diaire des deux variables structur´es :old et :new. Par exemple le trigger suivant empˆche
                           e                                  e                                                   e
de diminuer un salaire :
CREATE OR REPLACE TRIGGER pasDeBaisseDeSalaire
BEFORE UPDATE ON EMP
FOR EACH ROW
BEGIN
        IF ( : old . sal > : new . sal ) THEN
                   RAISE_APPLICATION_ERROR ( −20567 ,
                             ’ Pas de b a i s s e de s a l a i r e ! ’ ) ;
        END IF ;
END;


Tables en mutation
   Il est impossible, dans un trigger de type FOR EACH ROW de faire un SELECT sur la table en cours de modification.




                                                           20
SQL>   CREATE OR REPLACE TRIGGER beforeStatement
  2    BEFORE UPDATE ON CLIENT
  3    DECLARE
  4      NB N M E
             U B R;
  5    BEGIN
  6     SELECT C U T( ∗ ) INTO NB
                O N
  7     F O CLIENT ;
         R M
  8    END;
  9    /

D´ clencheur cr´ ´ .
 e             ee

SQL>
SQL>   CREATE OR REPLACE TRIGGER afterStatement
  2    AFTER UPDATE ON CLIENT
  3    DECLARE
  4      NB N M E
             U B R;
  5    BEGIN
  6     SELECT C U T( ∗ ) INTO NB
                O N
  7     F O CLIENT ;
         R M
  8    END;
  9    /

D´ clencheur cr´ ´ .
 e             ee

SQL>
SQL> UPDATE CLIENT SET nomcli = nomcli ;

21 ligne ( s ) mise ( s ) ` jour .
                          a

SQL>
SQL>   CREATE OR REPLACE TRIGGER beforeForEachRow
  2    BEFORE UPDATE ON CLIENT
  3    FOR EACH ROW
  4    DECLARE
  5      NB N M E
             U B R;
  6    BEGIN
  7     SELECT C U T( ∗ ) INTO NB
                O N
  8     F O CLIENT ;
         R M
  9    END;
 10    /

D´ clencheur cr´ ´ .
 e             ee

SQL>
SQL> UPDATE CLIENT SET nomcli = nomcli ;
UPDATE CLIENT SET nomcli = nomcli
        ∗
ERREUR ` la ligne 1 :
        a
ORA −04091: la table SCOTT . CLIENT est en mutation ; le d´ clencheur ou la
                                                          e
fonction ne peut la voir
ORA −06512: ` ”SCOTT.BEFOREFOREACHROW” , ligne 4
            a
ORA −04088: erreur lors d ex´ cution du d´ clencheur ’SCOTT.BEFOREFOREACHROW’
                              e           e


SQL> DROP TRIGGER beforeForEachRow ;

D´ clencheur supprim´ .
 e                  e



                                            21
SQL>
SQL>
SQL>    CREATE OR REPLACE TRIGGER afterForEachRow
  2     AFTER UPDATE ON CLIENT
  3     FOR EACH ROW
  4     DECLARE
  5       NB N M E
              U B R;
  6     BEGIN
  7      SELECT C U T( ∗ ) INTO NB
                 O N
  8      F O CLIENT ;
          R M
  9     END;
 10     /

D´ clencheur cr´ ´ .
 e             ee

SQL>
SQL> UPDATE CLIENT SET nomcli = nomcli ;
UPDATE CLIENT SET nomcli = nomcli
        ∗
ERREUR ` la ligne 1 :
        a
ORA −04091: la table SCOTT . CLIENT est en mutation ; le d´ clencheur ou la
                                                          e
fonction ne peut la voir
ORA −06512: ` ”SCOTT.AFTERFOREACHROW” , ligne 4
            a
ORA −04088: erreur lors d ex´ cution du d´ clencheur ’SCOTT.AFTERFOREACHROW’
                              e           e


1.8.5     Contourner le probl`me des tables en mutation
                             e
   Il existe plusieurs fa¸ons de contourner ce probl`me :
                         c                          e
   – Utiliser un STATEMENT trigger. Comme on ne sait pas quelles lignes ont ´t´ modifi´es, on est oblig´ de toutes
                                                                               ee         e                e
      les traiter. Cette approche pr´sente donc un inconv´nient majeur : elle nous am`ne ` effectuer de nombreux
                                     e                     e                            e a
      traitements inutiles.
   – En ayant des donn´es redondantes. Il suffit que les donn´es servant ` la v´rification se trouvent dans une autre
                           e                                  e            a   e
      table que celle en mutation. Cette m´thode a pour inconv´nient la m´moire occup´e et la quantit´ de code ` ´crire
                                          e                   e          e            e              e         ae
      pour maintenir la coh´rence des donn´es. Dans la plupart des cas, cette solution est malgr´ tout la meilleure.
                             e              e                                                   e

Colonnes suppl´mentaires
              e
   Par exemple, si l’on souhaite empˆcher un client d’avoir plus de 10 comptes en banque, une solution est de placer
                                      e
dans la table client une colonne contenant le nombre de comptes.
ALTER TABLE CLIENT A D nbComptes number ;
                    D
UPDATE CLIENT SET nbComptes = 0 ;

   Une fois cette table cr´e, il convient de s’assurer que les donn´es de la colonne nbComptes contient toujours les
                           e                                       e
bonnes valeurs. On le fait avec plusieurs sous-programmes :
CREATE OR REPLACE TRIGGER metAJourNbComptes
AFTER INSERT OR UPDATE OR DELETE ON COMPTECLIENT
BEGIN
        UPDATE CLIENT SET nbComptes =
                (
                SELECT C U T( ∗ )
                        O N
                F O COMPTECLIENT CC
                 R M
                W E E CC . numCli = numCli
                  HR
                 );
END;
/

CREATE OR REPLACE TRIGGER verifieNbComptes


                                                          22
BEFORE INSERT ON COMPTECLIENT
FOR EACH ROW
DECLARE
         nbComptes N M E
                      U B R;
BEGIN
        SELECT nbComptes INTO nbComptes
        F O CLIENT
         R M
        W E E numCli = : new . numcli ;
          HR
         IF ( nbComptes >= 1 0 ) THEN
                  RAISE_APPLICATION_ERROR ( −20556 ,
                  ’ Ce c l i e n t a d e j a t r o p de comptes ’ ) ;
        END IF ;
END;
/

   On peut affiner en rempla¸ant metAJourNbComptes par plusieurs sous-programmes :
                          c
CREATE OR REPLACE TRIGGER initialiseNbComptes
BEFORE INSERT ON CLIENT
FOR EACH ROW
BEGIN
 : new . nbComptes := 0 ;
END;
/

CREATE OR REPLACE TRIGGER metAJourNbComptes
AFTER INSERT OR UPDATE OR DELETE ON COMPTECLIENT
FOR EACH ROW
BEGIN
        IF DELETING OR UPDATING THEN
                 UPDATE CLIENT SET nbComptes = nbComptes − 1
                 W E E numcli = : old . numcli ;
                  HR
        END IF ;
        IF INSERTING OR UPDATING THEN
                 UPDATE CLIENT SET nbComptes = nbComptes + 1
                 W E E numcli = : new . numcli ;
                  HR
        END IF ;
END;
/


Tables suppl´mentaires
            e
    Si l’on souhaite par exemple empˆcher les circuits dans la table PERSONNE, il est n´cessaire de faire un parcours
                                      e                                                    e
de graphe. Ce qui n´cessite des SELECT dans la table en cours de mutation. La seule solution est dans ce cas d’avoir
                     e
une table miroir qui contient les colonnes cl´s primaire et ´trang`res de cette table, et de s’en servir pour d´tecter les
                                             e              e     e                                            e
circuits.
CREATE TABLE MIRRORPERSONNE
(
numpers N M E PRIMARY KEY,
         U BR
pere N M E ,
      U BR
mere N M E
      U BR
 );

   Nous allons ensuite proc´der de mˆme, en r´percutant chaque op´ration de PERSONNE sur MIRRORPERSONNE.
                           e        e        e                   e
CREATE OR REPLACE TRIGGER miseAJourMirrorPersonne
BEFORE UPDATE OR INSERT OR DELETE ON PERSONNE
FOR EACH ROW
BEGIN
        IF DELETING OR UPDATING THEN


                                                           23
DELETE F O MIRRORPERSONNE
                              R M
                      W E E numpers = : old . numpers ;
                       HR
           END IF ;
           IF INSERTING OR UPDATING THEN
                    INSERT INTO MIRRORPERSONNE VALUES
                     ( : new . numpers , : new . pere , : new . mere ) ;
           END IF ;
END;
/

    Une fois cela fait, il suffit de rechercher si une personne ins´r´e est une descendante d’elle mˆme dans MIRRORPERSONNE.
                                                                 ee                               e
CREATE OR REPLACE FUNCTION trouveCircuit ( current N M E , toFind N M E
                                                        U BR       U B R)
RETURN BOOLEAN IS
        numPere N M E
                  U B R;
        numMere N M E
                  U B R;
BEGIN
        IF ( current IS NULL) THEN
                 RETURN FALSE;
        END IF ;
        SELECT pere , mere INTO numPere , numMere
                 F O MIRRORPERSONNE
                  R M
                 W E E numPers = current ;
                   HR
        RETURN ( numPere = toFind OR numMere = toFind OR
                 trouveCircuit ( numPere , toFind ) OR
                 trouveCircuit ( numMere , toFind ) ) ;
END;
/

CREATE OR REPLACE TRIGGER verifieCircuit
AFTER UPDATE OR INSERT ON PERSONNE
FOR EACH ROW
BEGIN
        IF ( trouveCircuit ( : new . numPers , : new . numPers ) ) THEN
                 RAISE_APPLICATION_ERROR ( −20557 ,
                 ’ C i r c u i t dans l ’ ’ a r b r e g ´ n ´ a l o g i q u e . ’ ) ;
                                                        e e
        END IF ;
END;
/




                                                            24
1.9     Packages
1.9.1    Principe
    Un package est un ensemble de sous-programmes et de variables form´ par  e
    – Une sp´cification : d´claration de variables et de sous-programmes
               e            e
    – Un corps : impl´mentation des sous-programmes
                        e
    Tout ce qui se trouve dans la sp´cification doit se trouver dans le corps, mais la r´ciproque est fausse. Un package
                                    e                                                  e
satisfait les points suivants :
    – encapsulation : certains traitements sont masqu´s, seule la sp´cification du package est visible. Cela a pour
                                                          e               e
      avantage de simplifier la tˆche de celui qui va utiliser le package.
                                a
    – modularit´ : il est possible de d´velopper s´par´ment les diverses parties de l’application. le d´veloppement
                   e                     e           e e                                                  e
      devient ainsi un assemblage de package.
    Ces deux aspects fournissent une souplesse certaine au niveau du d´veloppement : il est possible de modifier le
                                                                            e
corps d’un package sans changer sa sp´cification, donc sans modifier le fonctionnement de l’application.
                                       e

1.9.2    Sp´cification
           e
   La syntaxe permettant de cr´er l’entˆte est la suivante :
                              e        e
CREATE OR REPLACE PACKAGE nompackage IS
/∗
        declarations
∗/
END nomPackage ;
/

   Par exemple,
CREATE OR REPLACE PACKAGE compteur IS
        procedure reset ;
        function nextValue return number ;
END compteur ;
/


1.9.3    Corps
   La syntaxe permettant de cr´er le corps est la suivante :
                              e
CREATE OR REPLACE PACKAGE BODY nompackage IS
/∗
        implementation
∗/
END nomPackage ;
/

   Par exemple,
CREATE OR REPLACE PACKAGE BODY compteur IS
        cpt N M E
             U B R := 0 ;

          PROCEDURE reset IS
          BEGIN
                  cpt := 0 ;
          END;

        FUNCTION nextValue RETURN N M E IS
                                   U BR
        BEGIN
                cpt := cpt + 1 ;
                RETURN cpt − 1 ;
        END;
END compteur ;


                                                          25
/

    On peut utiliser un package depuis n’importe quel script PL/SQL :
DECLARE
           nb N M E
               U B R;
BEGIN
          FOR nb IN 4 . . 2 0 LOOP
                   DBMS_OUTPUT . PUT_LINE ( COMPTEUR . nextValue ( ) ) ;
          END LOOP ;
          COMPTEUR . RESET ( ) ;
          FOR nb IN REVERSE 0 . . 1 0 LOOP
                   DBMS_OUTPUT . PUT_LINE ( COMPTEUR . nextValue ( ) ) ;
          END LOOP ;
END;
/




                                                        26
Chapitre 2

Exercices

2.1     Introduction au PL/SQL
Exercice 1
   Ecrivez un programme affectant les valeurs 1 et 2 ` deux variables a et b, puis permutant les valeurs de ces deux
                                                    a
variables.

Exercice 2
   Ecrivez un programme pla¸ant la valeur 10 dans une variable a, puis affichant la factorielle de a.
                           c

Exercice 3
   Ecrivez un programme pla¸ant les valeurs 48 et 84 dans deux variables a et b puis affichant le pgcd de a et b.
                           c




                                                        27
2.2     Tableaux et Structures
Exercice 1
  1. Cr´ez un type tableau pouvant contenir jusqu’` 50 entiers.
       e                                          a
  2. Cr´ez une variable de ce type , faites une allocation dynamique et dimensionnez ce tableau ` 20 emplacements.
       e                                                                                        a
  3. Placez dans ce tableau la liste des 20 premiers carr´s parfaits : 1, 4, 9, 16, 25, . . .
                                                         e
  4. Inversez l’ordre des ´l´ments du tableau
                          ee
  5. Affichez le tableau.

Exercice 2
  Triez le tableau pr´c´dent avec la m´thode du tri ` bulle.
                     e e              e             a

Exercice 3
  Recherchez, par dichotomie, si l’´l´ment 225 se trouve dans le tableau.
                                   ee

Exercice 4
  On impl´mente des listes chaˆ ees avec des tableaux de la sorte,
         e                    ın´

SET SERVEROUTPUT ON
DECLARE
-- Maillon d’une liste cha^n´e
                           ı e
TYPE CELL IS RECORD
(
-- Donn´e de chaque maillon
        e
data INTEGER,
-- Indice du maillon pr´c´dent de la liste,
                       e e
                -- -1 s’il n’y en a pas
previous INTEGER,
-- Indice du maillon suivant de la liste,
                -- -1 s’il n’y en a pas
next INTEGER
);
-- Type tableau contenant les maillons de la liste
TYPE TREE IS VARRAY (19) OF CELL;
-- Tableau contenant les maillons de la liste
t TREE;
-- indice du premier ´l´ment de la liste
                     e e
first integer;
-- indice du dernier ´l´ment de la liste
                     e e
last integer;
BEGIN
t := TREE();
t.extend(19);

-- Initialisation
FOR i IN 1..19 LOOP
t(i).data := power(i, 5) mod 19 ;
t(i).previous := i-1;
t(i).next := i+1;
END LOOP;
first := 1;
last := 19;
t(first).previous := -1;
t(last).next := -1;




                                                              28
-- Affichage
DECLARE
p integer := first;
BEGIN
WHILE p <> -1 LOOP
DBMS_OUTPUT.PUT_LINE(’(’ || p || ’, ’ ||
                         t(p).data || ’, ’ ||
t(p).previous || ’, ’ || t(p).next || ’)’);
p := t(p).next;
END LOOP;
END;
        /* Ecrivez la suite vous-m^me... */
                                  e
END;
/

   Inversez l’ordre des ´l´ments de la liste, sans changer les indices des maillons (seulement en modifiant le chaˆ
                        ee                                                                                       ınage).

Exercice 5
   Utilisez le tri ` bulle pour remettre les ´l´ments dans l’ordre. Les indications sont les mˆmes : ne d´placez pas les
                   a                         ee                                               e          e
maillons, vous n’avez le droit de toucher qu’au chaˆınage. Bon courage, l’aspirine n’est pas fournie.




                                                          29
2.3     Utilisation PL/SQL
   Nous travaillerons sur les donn´es A.6 et A.5.
                                  e
   Vous n’oublierez pas de placer des commit en des lieux bien choisis.

Exercice 1
   Vous remarquerez que les valeurs des numpers de la table PERSONNE forment une s´quence de nombres de 1 ` 21.
                                                                                        e                        a
Utilisez une boucle dans laquelle vous placerez une requˆte pour recopier les couples nom/pr´nom de la table personne
                                                        e                                   e
dans la table CLIENT.

Exercice 2
   Ecrivez un script r´cup´rant le client de cl´ primaire la plus ´lev´e, et injectant ce client dans la table PERSONNEL.
                      e   e                    e                  e e

Exercice 3
   Ouvrez un compte courant pour chaque personne, effectuez un d´pˆt en esp`ce ´gal ` numpers ∗ 100 euros.
                                                               e o        e e      a

Exercice 4
    Ouvrez un livret pour chaque personne ayant un numpers pair, faites un virement de leur compte courant vers ce
livret de sorte qu’il ne reste plus que 500 sur leur compte.




                                                           30
2.4     Exceptions
   Nous utiliserons les donn´es de A.7 et A.5
                            e
   Vous ˆtes invit´s ` modifier le code de la s´ance pr´c´dente. Chaque fois qu’un SELECT ... INTO ... sera effectu´,
         e        e a                         e       e e                                                        e
vous rattraperez les exceptions NO DATA FOUND et TOO MANY ROWS. A chaque insertion, vous ratrapperez l’exception
DUP VAL ON INDEX.

Exercice 1
   Faites de sorte que les scripts important les donn´es des tables CLIENT ne puissent ˆtre ex´cut´s qu’une seule fois.
                                                     e                                 e      e e

Exercice 2
    Les scripts remplissant la table Operation ne fonctionneront pas aujourd’hui... Mˆme s’il fonctionnaient la derni`re
                                                                                       e                              e
fois. Trouvez les codes d’erreurs des exceptions lev´es par ces scripts, rattrapez-les de la fa¸on la plus appropri´e qui
                                                    e                                          c                   e
soit.




                                                           31
2.5     Sous-programmes
Exercice 1
   Ecrire une fonction r´cursive retournant bn , avec n entier positif ou nul.
                        e

Exercice 2
   Am´liorer la fonction pr´c´dente en utilisant le fait que
     e                     e e
                                                                  n
                                                      bn = (b2 ) 2
   si n est pair.

Pour les questions suivantes, utilisez les donn´es de A.5.
                                               e

Exercice 3
    Ecrire une fonction demi-freres prenant deux num´ros de personnes en param`tre et retournant vrai si et seulement
                                                    e                         e
si ces deux personnes ont un parent en commun.

Exercice 4
   Ecrire une fonction cousins germains prenant deux num´ros de personnes en param`tre et retournant vrai si et
                                                            e                     e
seulement si ces deux deux individus sont cousins germains.

Exercice 5
   Ecrire une proc´dure r´cursive affichant le nom de la personne dont le num´ro est pass´ en param`tre et se rappellant
                  e      e                                                    e          e       e
r´cursivement sur le p`re de cette personne. Faites de sorte ` ne pas utiliser d’exceptions.
 e                    e                                      a

Exercice 6
    Ecrire une proc´dure r´cursive affichant les noms des ascendants de sexe masculin de la personne dont le num´ro
                   e      e                                                                                   e
est pass´ en param`tre.
        e          e

Exercice 7
   Ecrire une fonction r´cursive prenant deux num´ros de personne A et B et retournant vrai si A est un ascendant
                        e                        e
de B.

Exercice 8
    Ecrire une fonction prenant en param`tre deux num´ros de personne A et B et retournant, si l’un est un ascendant
                                          e             e
de l’autre, le nombre de g´n´rations les s´parant, −1 si l’un n’est pas un ascendant de l’autre.
                           e e            e

Exercice 9
   Pr´parez un verre d’aspirine et ´crivez une requˆte retournant le(s) couples(s) personnes s´par´es par le plus de
     e                             e               e                                          e e
g´n´rations.
 e e

Exercice 10
   Reprendre le code du tp pr´c´dent, le d´couper en sous-programmes de la fa¸on la moins inintelligente possible.
                             e e          e                                  c
Bon courage.




                                                             32
2.6    Curseurs
Exercice 1
  Refaites les exercices de 2.3 en utilisant les curseurs.

Exercice 2
  En utlisant les donnees A.5, ecrivez une fonction affichant toute la descendance d’une personne.




                                                             33
2.7     Curseurs parametr´s
                         e
   L’int´rˆt de ces exercices ´tant de vous familiariser avec les curseurs param´tr´s, vous ferez en sorte de ne pas
        ee                    e                                                 e e
contourner leur usage. Nous utiliserons les donn´es de A.6
                                                e

Exercice 1
   Ecrire une proc´dure qui affiche tous les clients, et pour chaque client, la liste des comptes.
                  e

Exercice 2
   Ecrire une proc´dure qui affiche tous les clients, et pour chaque client, la liste des comptes, et pour chacun de ces
                   e
comptes, l’historique des op´rations.
                            e




                                                          34
2.8     Triggers
   Impl´mentez les contraintes suivantes dans les donn´es de les donn´es de A.8. Vous ferez des sous-programmes
        e                                                e              e
tenant sur une page, et ne contenant pas plus de trois niveaux d’imbrication. Vous r´pertorierez les num´ros d’erreurs
                                                                                    e                   e
que vous affecterez a chaque lev´e d’exception.
                   `            e
  1. Il ne doit pas ˆtre possible de modifier la note min dans la table prerequis.
                    e
  2. Dans un module, il ne doit pas y avoir plus de effecMax ´l`ves inscrits.
                                                             ee
  3. On ne peut cr´er un examen pour un module que s’il y a des ´l`ves inscrits dans ce module.
                  e                                             ee
  4. Un ´l`ve ne peut passer un examen que si sa date d’inscription est ant´rieure ` la date de l’examen.
        ee                                                                 e       a
  5. Il ne doit pas y avoir de circuit dans la table prerequis (il existe une fa¸on de la v´rifier en PL/SQL, mais
                                                                                c          e
     comme vous ne la connaissez pas, faites un parcours en profondeur du graphe des pr´-requis)
                                                                                         e
  6. Un ´l`ve s’inscrivant ` un module doit avoir eu au moins la note min ` tous les modules pr´-requis.
        ee                 a                                              a                    e
  7. Ajouter dans ´tudiant un champ moyenne, celui-ci contiendra la moyenne de chaque ´tudiant s’il a pass´ les
                  e                                                                   e                   e
     examens de tous les modules dans lesquels il est inscrit.
  8. Revenez sur la premi`re contrainte : il ne doit ˆtre possible de modifier une note min dans la table prerequis que
                            e                         e
     s’il n’existe pas d’´l`ve dont une inscription serait invalid´e.
                         ee                                       e
  9. Il ne doit ˆtre possible de modifier effecMax que si des ´tudiants ne se retrouvent pas avec une inscription
                e                                            e
     invalid´e.
            e
   Libre ` vous par la suite de trouver d’autres contraintes et de les impl´menter.
         a                                                                 e




                                                         35
2.9          Packages
Exercice 1
   Lancez deux sessions simultan´ment sur le mˆme serveur et invoquez les sous-programmes du package compteur
                                 e             e
depuis chacune des sessions. Que remarquez-vous ?

Exercice 2
     Impl´menter le corps du package suivant (utilisez les donn´es de A.5).
         e                                                     e
CREATE OR R E P L A C E P A C K A G E g e s t i o n _ a r b r e I S
        c i r c u i t exception ;

              c u r s o r f e u i l l e s r e t u r n p e r s o n n e%r o w t y p e ;

              p r o c e d u r e a j o u t e P e r s o n n e ( n o m p e r s o n n e . n o m%t y p e ,
                                p r e n o m p e r s o n n e . p r e n o m%t y p e , p e r e p e r s o n n e . p e r e%t y p e ,
                                m e r e p e r s o n n e . m e r e%t y p e ) ;

              p r o c e d u r e m o d i f i e P a r e n t s ( p e r s p e r s o n n e . n u m p e r s%t y p e ,
                                n u m P e r e p e r s o n n e . p e r e%t y p e , n u m M e r e p e r s o n n e . m e r e%t y p e ) ;


END g e s t i o n _ a r b r e ;
/




                                                                                              36
2.10    R´visions
         e
  Impl´mentez les contraintes suivantes dans les donn´es de A.9.
      e                                              e
 1. Les parents d’une mˆme personne sont des personnes diff´rentes.
                       e                                  e
 2. L’arbre g´n´alogique ne contient pas de circuit.
             e e
 3. Les dates de divorce sont ult´rieures aux dates de mariage.
                                 e
 4. Une mˆme personne ne peut pas ˆtre mari´e ` plusieurs personnes simultan´ment.
         e                        e        e a                              e
 5. Personne ne peut ˆtre p`re d’une personne et m`re d’une autre.
                     e     e                      e
 6. Un mari ne peut pas ˆtre m`re et une femme ne peut pas ˆtre p`re.
                        e     e                            e     e
 7. Deux personnes ayant du sang en commun ne peuvent se marier.




                                                       37
Chapitre 3

Corrig´s
      e

3.1         Introduction au PL/SQL
−− E x e r c i c e 1

DECLARE
            a N ME
               U B R;
            b N ME
               U B R;
            t N ME
               U B R;
BEGIN
            a := 1 ;
            b := 2 ;
            DBMS_OUTPUT          . PUT_LINE ( ’a = ’ | | a ) ;
            DBMS_OUTPUT          . PUT_LINE ( ’b = ’ | | b ) ;
            DBMS_OUTPUT          . P U T _ L I N E ( ’ Let ’ ’ s swap a and b . . . The r e s u l t   is : ’ );
            t := a ;
            a := b ;
            b := t ;
            DBMS_OUTPUT          . PUT_LINE ( ’a = ’ | | a ) ;
            DBMS_OUTPUT          . PUT_LINE ( ’b = ’ | | b ) ;
END;
/

−− E x e r c i c e 2

DECLARE
            a N ME
               U B R;
            res N M E
                 U B R;
            counter N M E
                     U B R;
BEGIN
            a := 1 0 ;
            r e s := 1 ;
             c o u n t e r := a ;
            WHILE counter > 0 LOOP
                             r e s := r e s ∗ c o u n t e r ;
                             c o u n t e r := c o u n t e r − 1 ;
            END L O O P ;
             D B M S _ O U T P U T . P U T _ L I N E ( a | | ’ != ’ | | r e s ) ;
END;
/

−− E x e r c i c e 3

DECLARE
            a N M E := 4 8 ;
               U BR
            b N M E := 8 4 ;
               U BR
            amodb N M E
                   U B R;
BEGIN
             D B M S _ O U T P U T . P U T ( ’PGCD( ’ | | a | | ’ , ’ | | b | | ’ ) = ’ ) ;
            WHILE b > 0 LOOP
                             a m o d b := a ;
                             W H I L E a m o d b >= b L O O P
                                             a m o d b := a m o d b − b ;
                            END L O O P ;
                             a := b ;
                             b := a m o d b ;
            END L O O P ;
             DBMS_OUTPUT . PUT_LINE ( a ) ;
END;
/




                                                                                          38
3.2         Tableaux et Structures
SET S E R V E R O U T P U T ON

−− Tableaux

DECLARE
            T Y P E m o n t a b I S V A R R A Y ( 5 0 ) O F INTEGER ;
            t montab ;
BEGIN
            t := m o n t a b ( ) ;
            t . extend ( 2 0 ) ;

            −− I n i t i a l i s a t i o n
            F O R i IN 1 . . 2 0 L O O P
                         t ( i ) := i ∗ i ;
            END L O O P ;


            −− I n v e r s i o n de l ’ o r d r e d e s ´ l´ m e n t s
                                                        e e
             DECLARE
                         temp i n t e g e r ;
            BEGIN
                         F O R i IN 1 . . 1 0 L O O P
                                    t e m p := t ( i ) ;
                                    t ( i ) := t (20− i + 1 ) ;
                                    t (20− i +1) := t e m p ;
                        END L O O P ;
            END;


            −− A f f i c h a g e
            F O R i IN 1 . . 2 0 L O O P
                         DBMS_OUTPUT . PUT_LINE ( ’ t ( ’ | |
                                   i || ’) = ’ || t(i ));
            END L O O P ;

            −− Tri ` b u l l e
                     a
             DECLARE
                       temp i n t e g e r ;
            BEGIN
                       F O R i IN R E V E R S E 2 . . 2 0 L O O P
                                  F O R j IN 2 . . i L O O P
                                               IF t ( j − 1) > t ( j ) T E    H N
                                                            t e m p := t ( j ) ;
                                                            t ( j ) := t ( j − 1 ) ;
                                                            t ( j −1) := t e m p ;
                                               END I F ;
                                 END L O O P ;
                      END L O O P ;
            END;

            −− A f f i c h a g e
            F O R i IN 1 . . 2 0 L O O P
                         DBMS_OUTPUT . PUT_LINE ( ’ t ( ’ | |
                                   i || ’) = ’ || t(i ));
            END L O O P ;

            −− Recherche par d i c h o t o m i e de l ’ ´ l´ m e n t 225
                                                          e e
             DECLARE
                     i n f INTEGER := 1 ;
                     s u p INTEGER := 2 0 ;
                     m INTEGER ;
                     X INTEGER := 4 0 0 ;
            BEGIN
                     LOOP
                                 DBMS_OUTPUT . PUT_LINE ( ’ i n f = ’ | | inf          ||
                                                        ’ ; sup = ’ | | s u p ) ;
                                 m := ( i n f + s u p ) / 2 ;
                                 EXIT W E HN
                                            t ( m ) = X OR i n f = s u p ;
                                 IF t ( m ) > X T E H N
                                            s u p := m −1;
                                ELSE
                                            i n f := m +1;
                                END I F ;
                     END L O O P ;
                     IF t ( m ) = X T E H N
                                 DBMS_OUTPUT . PUT_LINE ( X | |
                                 ’ e s t dans l e t a b l e a u ’ ) ;
                     ELSE
                                 DBMS_OUTPUT . PUT_LINE ( X | |
                                 ’ n” e s t pas dans l e t a b l e a u ’ ) ;
                     END I F ;
            END;
END;
/




                                                                               39
−− S t r u c t u r e s

DECLARE
             −− M a i l l o n d ’ une l i s t e c h aˆn´ e
                                                      ı e
             TYPE CELL IS RECORD
             (
                          −− Donn´e de chaque m a i l l o n
                                        e
                          d a t a INTEGER,
                          −− I n d i c e du m a i l l o n p r´ c´ d e n t de l a l i s t e ,
                                                              e e
                          −− −1 s ’ i l n ’ y en a pas
                          p r e v i o u s INTEGER,
                          −− I n d i c e du m a i l l o n s u i v a n t de l a l i s t e ,
                          −− −1 s ’ i l n ’ y en a pas
                          next INTEGER
              );
             −− Type t a b l e a u c o n t e n a n t l e s m a i l l o n s de l a l i s t e
             TYPE TREE IS VARRAY ( 1 9 ) OF CELL ;
             −− Tableau c o n t e n a n t l e s m a i l l o n s de l a l i s t e
             t TREE ;
             −− i n d i c e du premier ´ l´ m e n t de l a l i s t e
                                              e e
             first integer ;
             −− i n d i c e du d e r n i e r ´ l´ m e n t de l a l i s t e
                                              e e
             last integer ;
BEGIN
              t := T R E E ( ) ;
              t . extend ( 1 9 ) ;

             −− I n i t i a l i s a t i o n
             F O R i IN 1 . . 1 9 L O O P
                             t ( i ) . d a t a := p o w e r ( i , 5 ) m o d 19 ;
                             t ( i ) . p r e v i o u s := i −1;
                             t ( i ) . next := i +1;
             END L O O P ;
              f i r s t := 1 ;
              l a s t := 1 9 ;
             t ( f i r s t ) . p r e v i o u s := −1;
             t ( l a s t ) . next := −1;

             −− A f f i c h a g e
              DECLARE
                          p i n t e g e r := f i r s t ;
             BEGIN
                          W H I L E p <> −1 L O O P
                                        DBMS_OUTPUT . PUT_LINE ( ’ ( ’ | | p | |               ’, ’   ||
                                                   t ( p ) . data | | ’ , ’ | |
                                                   t ( p ) . previous | | ’ , ’ | |
                                                   t ( p ) . next | | ’ ) ’ ) ;
                                        p := t ( p ) . next ;
                         END L O O P ;
             END;

             −− I n v e r s i o n de l ’ o r d r e d e s ´ l´ m e n t s
                                                              e e
              DECLARE
                          t e m p INTEGER ;
             BEGIN
                          F O R i IN 1 . . 1 9 L O O P
                                      t e m p := t ( i ) . p r e v i o u s ;
                                      t ( i ) . p r e v i o u s := t ( i ) . next ;
                                      t ( i ) . next := t e m p ;
                         END L O O P ;
                          f i r s t := 1 9 ;
                          l a s t := 1 ;
             END;

             −− A f f i c h a g e
              DECLARE
                          p i n t e g e r := f i r s t ;
             BEGIN
                          W H I L E p <> −1 L O O P
                                        DBMS_OUTPUT . PUT_LINE ( ’ ( ’ | |
                                                   p || ’ , ’ ||
                                                   t ( p ) . data | | ’ , ’ | |
                                                   t ( p ) . previous | | ’ , ’           ||
                                                   t ( p ) . next | | ’ ) ’ ) ;
                                        p := t ( p ) . next ;
                         END L O O P ;
             END;

             −− Tri ` b u l l e
                     a
             DECLARE
                       i i n t e g e r := l a s t ;
                       j integer ;
             BEGIN
                       W H I L E t ( t ( i ) . p r e v i o u s ) . p r e v i o u s <> −1 L O O P
                                     j := f i r s t ;
                                     W H I L E i<   >j L O O P

                                                     I F ( t ( j ) . d a t a > t ( t ( j ) . next ) . d a t a ) T E
                                                                                                                 H N




                                                                                       40
Oracle
Oracle
Oracle
Oracle
Oracle
Oracle
Oracle
Oracle
Oracle
Oracle
Oracle
Oracle
Oracle
Oracle
Oracle
Oracle
Oracle
Oracle
Oracle
Oracle
Oracle
Oracle
Oracle
Oracle
Oracle
Oracle
Oracle
Oracle
Oracle
Oracle
Oracle
Oracle
Oracle
Oracle
Oracle
Oracle
Oracle
Oracle

Weitere ähnliche Inhalte

Was ist angesagt?

89302f111f notice installation flotax fb
89302f111f   notice installation flotax fb89302f111f   notice installation flotax fb
89302f111f notice installation flotax fblefilsduforgeron
 
oecoil condens-2-notice-utilisation
oecoil condens-2-notice-utilisationoecoil condens-2-notice-utilisation
oecoil condens-2-notice-utilisationClothildeBenares
 
214275799 cours-cned-6-eme-maths
214275799 cours-cned-6-eme-maths214275799 cours-cned-6-eme-maths
214275799 cours-cned-6-eme-mathsEttaoufik Elayedi
 
The Ring programming language version 1.5.2 book - Part 1 of 181
The Ring programming language version 1.5.2 book - Part 1 of 181The Ring programming language version 1.5.2 book - Part 1 of 181
The Ring programming language version 1.5.2 book - Part 1 of 181Mahmoud Samir Fayed
 
The Ring programming language version 1.6 book - Part 1 of 189
The Ring programming language version 1.6 book - Part 1 of 189The Ring programming language version 1.6 book - Part 1 of 189
The Ring programming language version 1.6 book - Part 1 of 189Mahmoud Samir Fayed
 
Ozw772.250 mise en_service_fr
Ozw772.250 mise en_service_frOzw772.250 mise en_service_fr
Ozw772.250 mise en_service_fre-genieclimatique
 
Support formation vidéo : Excel 2016 - Maîtrisez les bases
Support formation vidéo : Excel 2016 - Maîtrisez les basesSupport formation vidéo : Excel 2016 - Maîtrisez les bases
Support formation vidéo : Excel 2016 - Maîtrisez les basesSmartnSkilled
 
Manuel du module additionnel RF-LAMINATE pour RFEM
Manuel du module additionnel RF-LAMINATE pour RFEMManuel du module additionnel RF-LAMINATE pour RFEM
Manuel du module additionnel RF-LAMINATE pour RFEMGrégoire Dupont
 
Ing ordre generique_tpv_serveur 0.8
Ing ordre generique_tpv_serveur 0.8Ing ordre generique_tpv_serveur 0.8
Ing ordre generique_tpv_serveur 0.8Lokesh Kumar
 
The Ring programming language version 1.3 book - Part 1 of 88
The Ring programming language version 1.3 book - Part 1 of 88The Ring programming language version 1.3 book - Part 1 of 88
The Ring programming language version 1.3 book - Part 1 of 88Mahmoud Samir Fayed
 
Sout3
Sout3Sout3
Sout33on
 
Instruction Manual | Celestron AstroMaster EQ | Telescopes | Optics Trade
Instruction Manual | Celestron AstroMaster EQ | Telescopes | Optics TradeInstruction Manual | Celestron AstroMaster EQ | Telescopes | Optics Trade
Instruction Manual | Celestron AstroMaster EQ | Telescopes | Optics TradeOptics-Trade
 
The Ring programming language version 1.10 book - Part 3 of 212
The Ring programming language version 1.10 book - Part 3 of 212The Ring programming language version 1.10 book - Part 3 of 212
The Ring programming language version 1.10 book - Part 3 of 212Mahmoud Samir Fayed
 
The Ring programming language version 1.7 book - Part 1 of 196
The Ring programming language version 1.7 book - Part 1 of 196The Ring programming language version 1.7 book - Part 1 of 196
The Ring programming language version 1.7 book - Part 1 of 196Mahmoud Samir Fayed
 
The Ring programming language version 1.8 book - Part 1 of 202
The Ring programming language version 1.8 book - Part 1 of 202The Ring programming language version 1.8 book - Part 1 of 202
The Ring programming language version 1.8 book - Part 1 of 202Mahmoud Samir Fayed
 

Was ist angesagt? (20)

89302f111f notice installation flotax fb
89302f111f   notice installation flotax fb89302f111f   notice installation flotax fb
89302f111f notice installation flotax fb
 
oecoil condens-2-notice-utilisation
oecoil condens-2-notice-utilisationoecoil condens-2-notice-utilisation
oecoil condens-2-notice-utilisation
 
214275799 cours-cned-6-eme-maths
214275799 cours-cned-6-eme-maths214275799 cours-cned-6-eme-maths
214275799 cours-cned-6-eme-maths
 
The Ring programming language version 1.5.2 book - Part 1 of 181
The Ring programming language version 1.5.2 book - Part 1 of 181The Ring programming language version 1.5.2 book - Part 1 of 181
The Ring programming language version 1.5.2 book - Part 1 of 181
 
The Ring programming language version 1.6 book - Part 1 of 189
The Ring programming language version 1.6 book - Part 1 of 189The Ring programming language version 1.6 book - Part 1 of 189
The Ring programming language version 1.6 book - Part 1 of 189
 
Programmation en-java-api
Programmation en-java-apiProgrammation en-java-api
Programmation en-java-api
 
Ozw772.250 mise en_service_fr
Ozw772.250 mise en_service_frOzw772.250 mise en_service_fr
Ozw772.250 mise en_service_fr
 
Support formation vidéo : Excel 2016 - Maîtrisez les bases
Support formation vidéo : Excel 2016 - Maîtrisez les basesSupport formation vidéo : Excel 2016 - Maîtrisez les bases
Support formation vidéo : Excel 2016 - Maîtrisez les bases
 
20081219 bda10964fr-1
20081219 bda10964fr-120081219 bda10964fr-1
20081219 bda10964fr-1
 
Manuel du module additionnel RF-LAMINATE pour RFEM
Manuel du module additionnel RF-LAMINATE pour RFEMManuel du module additionnel RF-LAMINATE pour RFEM
Manuel du module additionnel RF-LAMINATE pour RFEM
 
Ing ordre generique_tpv_serveur 0.8
Ing ordre generique_tpv_serveur 0.8Ing ordre generique_tpv_serveur 0.8
Ing ordre generique_tpv_serveur 0.8
 
Complet
CompletComplet
Complet
 
The Ring programming language version 1.3 book - Part 1 of 88
The Ring programming language version 1.3 book - Part 1 of 88The Ring programming language version 1.3 book - Part 1 of 88
The Ring programming language version 1.3 book - Part 1 of 88
 
Sout3
Sout3Sout3
Sout3
 
PMP Report
PMP ReportPMP Report
PMP Report
 
Instruction Manual | Celestron AstroMaster EQ | Telescopes | Optics Trade
Instruction Manual | Celestron AstroMaster EQ | Telescopes | Optics TradeInstruction Manual | Celestron AstroMaster EQ | Telescopes | Optics Trade
Instruction Manual | Celestron AstroMaster EQ | Telescopes | Optics Trade
 
The Ring programming language version 1.10 book - Part 3 of 212
The Ring programming language version 1.10 book - Part 3 of 212The Ring programming language version 1.10 book - Part 3 of 212
The Ring programming language version 1.10 book - Part 3 of 212
 
TCB
TCBTCB
TCB
 
The Ring programming language version 1.7 book - Part 1 of 196
The Ring programming language version 1.7 book - Part 1 of 196The Ring programming language version 1.7 book - Part 1 of 196
The Ring programming language version 1.7 book - Part 1 of 196
 
The Ring programming language version 1.8 book - Part 1 of 202
The Ring programming language version 1.8 book - Part 1 of 202The Ring programming language version 1.8 book - Part 1 of 202
The Ring programming language version 1.8 book - Part 1 of 202
 

Andere mochten auch

Bornes de recharges_-_la_filiere_dispose_de_son_referentiel
Bornes de recharges_-_la_filiere_dispose_de_son_referentielBornes de recharges_-_la_filiere_dispose_de_son_referentiel
Bornes de recharges_-_la_filiere_dispose_de_son_referentielDominique Gayraud
 
Spiruline biblio generale.2007.-.antenna.ch.34p
Spiruline biblio generale.2007.-.antenna.ch.34pSpiruline biblio generale.2007.-.antenna.ch.34p
Spiruline biblio generale.2007.-.antenna.ch.34ptawfikh9
 
- IHEC (Présentation HEC PREPA)
- IHEC (Présentation HEC PREPA)- IHEC (Présentation HEC PREPA)
- IHEC (Présentation HEC PREPA)Farah Zéga
 
Atelier EXCEL : Les fonctions financières
Atelier EXCEL :  Les fonctions financièresAtelier EXCEL :  Les fonctions financières
Atelier EXCEL : Les fonctions financièresZakariyaa AIT ELMOUDEN
 
Relance economique locale ECOLOC
Relance economique locale ECOLOCRelance economique locale ECOLOC
Relance economique locale ECOLOCregiosuisse
 
Analyse Financiere Des Projets
Analyse Financiere Des ProjetsAnalyse Financiere Des Projets
Analyse Financiere Des ProjetsOURAHOU Mohamed
 
Petit guide des possibilités d'utilisation du logiciel scratch en technologie
Petit guide des possibilités d'utilisation du logiciel scratch en technologiePetit guide des possibilités d'utilisation du logiciel scratch en technologie
Petit guide des possibilités d'utilisation du logiciel scratch en technologieخالد المشكوري
 

Andere mochten auch (10)

Bornes de recharges_-_la_filiere_dispose_de_son_referentiel
Bornes de recharges_-_la_filiere_dispose_de_son_referentielBornes de recharges_-_la_filiere_dispose_de_son_referentiel
Bornes de recharges_-_la_filiere_dispose_de_son_referentiel
 
La centrale solaire Noor
La centrale solaire NoorLa centrale solaire Noor
La centrale solaire Noor
 
Excel : Les fonctions mathématiques
Excel : Les fonctions mathématiquesExcel : Les fonctions mathématiques
Excel : Les fonctions mathématiques
 
Spiruline biblio generale.2007.-.antenna.ch.34p
Spiruline biblio generale.2007.-.antenna.ch.34pSpiruline biblio generale.2007.-.antenna.ch.34p
Spiruline biblio generale.2007.-.antenna.ch.34p
 
- IHEC (Présentation HEC PREPA)
- IHEC (Présentation HEC PREPA)- IHEC (Présentation HEC PREPA)
- IHEC (Présentation HEC PREPA)
 
Atelier EXCEL : Les fonctions financières
Atelier EXCEL :  Les fonctions financièresAtelier EXCEL :  Les fonctions financières
Atelier EXCEL : Les fonctions financières
 
Relance economique locale ECOLOC
Relance economique locale ECOLOCRelance economique locale ECOLOC
Relance economique locale ECOLOC
 
COURS GEOCHIMIE
COURS GEOCHIMIE COURS GEOCHIMIE
COURS GEOCHIMIE
 
Analyse Financiere Des Projets
Analyse Financiere Des ProjetsAnalyse Financiere Des Projets
Analyse Financiere Des Projets
 
Petit guide des possibilités d'utilisation du logiciel scratch en technologie
Petit guide des possibilités d'utilisation du logiciel scratch en technologiePetit guide des possibilités d'utilisation du logiciel scratch en technologie
Petit guide des possibilités d'utilisation du logiciel scratch en technologie
 

Ähnlich wie Oracle

courspython3.pdf
courspython3.pdfcourspython3.pdf
courspython3.pdfDendouga1
 
Base-de-données.pdf
Base-de-données.pdfBase-de-données.pdf
Base-de-données.pdfdjallel2
 
The Ring programming language version 1.5.4 book - Part 1 of 185
The Ring programming language version 1.5.4 book - Part 1 of 185The Ring programming language version 1.5.4 book - Part 1 of 185
The Ring programming language version 1.5.4 book - Part 1 of 185Mahmoud Samir Fayed
 
The Ring programming language version 1.5.3 book - Part 1 of 184
The Ring programming language version 1.5.3 book - Part 1 of 184The Ring programming language version 1.5.3 book - Part 1 of 184
The Ring programming language version 1.5.3 book - Part 1 of 184Mahmoud Samir Fayed
 
Crown tsp6000 series turret order picker service repair manual
Crown tsp6000 series turret order picker service repair manualCrown tsp6000 series turret order picker service repair manual
Crown tsp6000 series turret order picker service repair manualudjdkdkdmm
 
Crown tsp6000 series turret order picker service repair manual
Crown tsp6000 series turret order picker service repair manualCrown tsp6000 series turret order picker service repair manual
Crown tsp6000 series turret order picker service repair manualfhhsjdkmem
 
Crown tsp6000 series turret order picker service repair manual
Crown tsp6000 series turret order picker service repair manualCrown tsp6000 series turret order picker service repair manual
Crown tsp6000 series turret order picker service repair manualjfksekmmdme
 
Cours stochastic processes
Cours stochastic processesCours stochastic processes
Cours stochastic processeszoolyver
 
Rg total co p f_mars2012_sans changements visibles-f
Rg total co p f_mars2012_sans changements visibles-fRg total co p f_mars2012_sans changements visibles-f
Rg total co p f_mars2012_sans changements visibles-fcreapik
 
The Ring programming language version 1.2 book - Part 1 of 84
The Ring programming language version 1.2 book - Part 1 of 84The Ring programming language version 1.2 book - Part 1 of 84
The Ring programming language version 1.2 book - Part 1 of 84Mahmoud Samir Fayed
 
Extrait ouvrage 65_outils_du_changement_arnaud_tonnele
Extrait ouvrage 65_outils_du_changement_arnaud_tonneleExtrait ouvrage 65_outils_du_changement_arnaud_tonnele
Extrait ouvrage 65_outils_du_changement_arnaud_tonneleSandra Santana
 
Mémoire fin d'étude gestion des interventions
Mémoire fin d'étude gestion des interventionsMémoire fin d'étude gestion des interventions
Mémoire fin d'étude gestion des interventionsMohamed Arar
 
The Ring programming language version 1.4 book - Part 1 of 30
The Ring programming language version 1.4 book - Part 1 of 30The Ring programming language version 1.4 book - Part 1 of 30
The Ring programming language version 1.4 book - Part 1 of 30Mahmoud Samir Fayed
 
The Ring programming language version 1.10 book - Part 1 of 212
The Ring programming language version 1.10 book - Part 1 of 212The Ring programming language version 1.10 book - Part 1 of 212
The Ring programming language version 1.10 book - Part 1 of 212Mahmoud Samir Fayed
 

Ähnlich wie Oracle (20)

courspython3.pdf
courspython3.pdfcourspython3.pdf
courspython3.pdf
 
Manuel 3
Manuel 3Manuel 3
Manuel 3
 
Base-de-données.pdf
Base-de-données.pdfBase-de-données.pdf
Base-de-données.pdf
 
Analyse s1
Analyse s1Analyse s1
Analyse s1
 
The Ring programming language version 1.5.4 book - Part 1 of 185
The Ring programming language version 1.5.4 book - Part 1 of 185The Ring programming language version 1.5.4 book - Part 1 of 185
The Ring programming language version 1.5.4 book - Part 1 of 185
 
8.02 introduction to electrodynamics 3e-griffiths
8.02 introduction to electrodynamics 3e-griffiths8.02 introduction to electrodynamics 3e-griffiths
8.02 introduction to electrodynamics 3e-griffiths
 
The Ring programming language version 1.5.3 book - Part 1 of 184
The Ring programming language version 1.5.3 book - Part 1 of 184The Ring programming language version 1.5.3 book - Part 1 of 184
The Ring programming language version 1.5.3 book - Part 1 of 184
 
Crown tsp6000 series turret order picker service repair manual
Crown tsp6000 series turret order picker service repair manualCrown tsp6000 series turret order picker service repair manual
Crown tsp6000 series turret order picker service repair manual
 
Crown tsp6000 series turret order picker service repair manual
Crown tsp6000 series turret order picker service repair manualCrown tsp6000 series turret order picker service repair manual
Crown tsp6000 series turret order picker service repair manual
 
Crown tsp6000 series turret order picker service repair manual
Crown tsp6000 series turret order picker service repair manualCrown tsp6000 series turret order picker service repair manual
Crown tsp6000 series turret order picker service repair manual
 
Cours stochastic processes
Cours stochastic processesCours stochastic processes
Cours stochastic processes
 
Rg total co p f_mars2012_sans changements visibles-f
Rg total co p f_mars2012_sans changements visibles-fRg total co p f_mars2012_sans changements visibles-f
Rg total co p f_mars2012_sans changements visibles-f
 
Jmetertest
JmetertestJmetertest
Jmetertest
 
Guide projet Iset
Guide projet IsetGuide projet Iset
Guide projet Iset
 
The Ring programming language version 1.2 book - Part 1 of 84
The Ring programming language version 1.2 book - Part 1 of 84The Ring programming language version 1.2 book - Part 1 of 84
The Ring programming language version 1.2 book - Part 1 of 84
 
Extrait ouvrage 65_outils_du_changement_arnaud_tonnele
Extrait ouvrage 65_outils_du_changement_arnaud_tonneleExtrait ouvrage 65_outils_du_changement_arnaud_tonnele
Extrait ouvrage 65_outils_du_changement_arnaud_tonnele
 
Mémoire fin d'étude gestion des interventions
Mémoire fin d'étude gestion des interventionsMémoire fin d'étude gestion des interventions
Mémoire fin d'étude gestion des interventions
 
Report MyProof
Report MyProofReport MyProof
Report MyProof
 
The Ring programming language version 1.4 book - Part 1 of 30
The Ring programming language version 1.4 book - Part 1 of 30The Ring programming language version 1.4 book - Part 1 of 30
The Ring programming language version 1.4 book - Part 1 of 30
 
The Ring programming language version 1.10 book - Part 1 of 212
The Ring programming language version 1.10 book - Part 1 of 212The Ring programming language version 1.10 book - Part 1 of 212
The Ring programming language version 1.10 book - Part 1 of 212
 

Oracle

  • 1. Introduction au PL/SQL Oracle Alexandre Mesl´ e 17 octobre 2011
  • 2. Table des mati`res e 1 Notes de cours 3 1.1 Introduction au PL/SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 1.1.1 PL/SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 1.1.2 Blocs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 1.1.3 Affichage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 1.1.4 Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 1.1.5 Traitements conditionnels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 1.1.6 Traitements r´p´titifs . . . . . . . . . . . . . . e e . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 1.2 Tableaux et structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 1.2.1 Tableaux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 1.2.2 Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 1.3 Utilisation du PL/SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 1.3.1 Affectation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 1.3.2 Tables et structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 1.3.3 Transactions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 1.4 Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 1.4.1 Rattraper une exception . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 1.4.2 Exceptions pr´d´finies . . . . . . . . . . . . . . e e . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 1.4.3 Codes d’erreur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 1.4.4 D´clarer et lancer ses propres exceptions . . . . e . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 1.5 Sous-programmes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 1.5.1 Proc´dures . . . . . . . . . . . . . . . . . . . . e . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 1.5.2 Fonctions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 1.6 Curseurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 1.6.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 1.6.2 Les curseurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 1.7 Curseurs parametr´s . . . . . . . . . . . . . . . . . . . e . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 1.7.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 1.7.2 D´finition . . . . . . . . . . . . . . . . . . . . . e . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 1.7.3 D´claration . . . . . . . . . . . . . . . . . . . . e . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 1.7.4 Ouverture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 1.7.5 Lecture d’une ligne, fermeture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 1.7.6 Boucle pour . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 1.7.7 Exemple r´capitulatif . . . . . . . . . . . . . . e . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 1.8 Triggers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 1.8.1 Principe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 1.8.2 Classification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 1.8.3 Cr´ation . . . . . . . . . . . . . . . . . . . . . . e . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 1.8.4 Acc`s aux lignes en cours de modification . . . e . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 1.8.5 Contourner le probl`me des tables en mutation e . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 1.9 Packages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 1.9.1 Principe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 1.9.2 Sp´cification . . . . . . . . . . . . . . . . . . . e . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 1.9.3 Corps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 1
  • 3. 2 Exercices 27 2.1 Introduction au PL/SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 2.2 Tableaux et Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 2.3 Utilisation PL/SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 2.4 Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 2.5 Sous-programmes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 2.6 Curseurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 2.7 Curseurs parametr´s . . . e . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 2.8 Triggers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 2.9 Packages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 2.10 R´visions . . . . . . . . . e . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 3 Corrig´s e 38 3.1 Introduction au PL/SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 3.2 Tableaux et Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 3.3 Application du PL/SQL et Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 3.4 Sous-programmes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 3.5 Curseurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 3.6 Curseurs param´tr´s . . . . . . . . . . e e . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 3.7 Triggers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 3.8 Packages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 3.9 R´visions . . . . . . . . . . . . . . . . e . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 A Scripts de cr´ation de bases e 67 A.1 Livraisons Sans contraintes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 A.2 Modules et prerequis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 A.3 G´om´trie . . . . . . . . . . . . . . e e . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 A.4 Livraisons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 A.5 Arbre g´n´alogique . . . . . . . . . e e . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 A.6 Comptes bancaires . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72 A.7 Comptes bancaires avec exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 A.8 Secr´tariat p´dagogique . . . . . . e e . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 A.9 Mariages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 2
  • 4. Chapitre 1 Notes de cours 1.1 Introduction au PL/SQL 1.1.1 PL/SQL Le PL de PL/SQL signifie Procedural Language. Il s’agit d’une extension proc´durale du SQL permettant d’effectuer e des traitements complexes sur une base de donn´es. Les possibilit´s offertes sont les mˆmes qu’avec des langages e e e imp´ratifs (instructions en s´quence) classiques. e e Ecrivez-le dans un ´diteur dont vous copierez le contenu dans SQL+. Un script ´crit en PL/SQL se termine obliga- e e toirement par un /, sinon SQL+ ne l’interpr`te pas. S’il contient des erreurs de compilation, il est possible d’afficher les e messages d’erreur avec la commande SQL+ : SHOW ERRORS. 1.1.2 Blocs Tout code ´crit dans un langage proc´dural est form´ de blocs. Chaque bloc comprend une section de d´claration e e e e de variables, et un ensemble d’instructions dans lequel les variables d´clar´es sont visibles. e e La syntaxe est DECLARE /∗ d e c l a r a t i o n de v a r i a b l e s ∗/ BEGIN /∗ i n s t r u c t i o n s a e x e c u t e r ∗/ END; 1.1.3 Affichage Pour afficher le contenu d’une variable, les proc´dures DBMS OUTPUT.PUT() et DBMS OUTPUT.PUT LINE() prennent e en argument une valeur ` afficher ou une variable dont la valeur est ` afficher. Par d´faut, les fonctions d’affichage a a e sont desactiv´es. Il convient, ` moins que vous ne vouliez rien voir s’afficher, de les activer avec la commande SQL+ e a SET SERVEROUTPUT ON. 1.1.4 Variables Une variable se d´clare de la sorte : e nom type [ : = initialisation ] ; L’initisation est optionnelle. Nous utiliserons les mˆmes types primitifs que dans les tables. Par exemple : e SET SERVEROUTPUT ON DECLARE c varchar2 ( 1 5 ) := ’ H e l l o World ! ’ ; BEGIN DBMS_OUTPUT . PUT_LINE ( c ) ; END; / Les affectations se font avec la syntaxe variable := valeur ; 3
  • 5. 1.1.5 Traitements conditionnels Le IF et le CASE fonctionnent de la mˆme fa¸on que dans les autres langages imp´ratifs : e c e IF /∗ c o n d i t i o n 1 ∗/ THEN /∗ i n s t r u c t i o n s 1 ∗/ ELSE /∗ i n s t r u c t i o n s 2 ∗/ END IF ; voire IF /∗ c o n d i t i o n 1 ∗/ THEN /∗ i n s t r u c t i o n s 1 ∗/ ELSIF /∗ c o n d i t i o n 2 ∗/ /∗ i n s t r u c t i o n s 2 ∗/ ELSE /∗ i n s t r u c t i o n s 3 ∗/ END IF ; Les conditions sont les mˆmes qu’en SQL. Le switch du langage C s’impl´mente en PL/SQL de la fa¸on suivante : e e c CASE /∗ v a r i a b l e ∗/ W E /∗ v a l e u r 1 ∗/ THEN HN /∗ i n s t r u c t i o n s 1 ∗/ W E /∗ v a l e u r 2 ∗/ THEN HN /∗ i n s t r u c t i o n s 2 ∗/ ... W E /∗ v a l e u r n ∗/ THEN HN /∗ i n s t r u c t i o n s n ∗/ ELSE /∗ i n s t r u c t i o n s par d ´ f a u t ∗/ e END CASE; 1.1.6 Traitements r´p´titifs e e LOOP ... END LOOP ; permet d’impl´menter les boucles e LOOP /∗ i n s t r u c t i o n s ∗/ END LOOP ; L’instruction EXIT WHEN permet de quitter une boucle. LOOP /∗ i n s t r u c t i o n s ∗/ EXIT W E /∗ c o n d i t i o n ∗/ ; HN END LOOP ; La boucle FOR existe aussi en PL/SQL : FOR /∗ v a r i a b l e ∗/ IN /∗ i n f ∗/ . . /∗ sup ∗/ LOOP /∗ i n s t r u c t i o n s ∗/ END LOOP ; Ainsi que la boucle WHILE : WHILE /∗ c o n d i t i o n ∗/ LOOP /∗ i n s t r u c t i o n s ∗/ END LOOP ; Est-il possible, en bidouillant, d’impl´menter une boucle DO ... WHILE ? e 4
  • 6. 1.2 Tableaux et structures 1.2.1 Tableaux Cr´ation d’un type tableau e Les types tableau doivent ˆtre d´finis explicitement par une d´claration de la forme e e e TYPE /∗ t y p e ∗/ IS VARRAY ( /∗ t a i l l e ∗/ ) OF /∗ t y p e E l e m e n t s ∗/ ; – type est le nom du type tableau cr´e par cette instruction e – taille est le nombre maximal d’´l´ments qu’il est possible de placer dans le tableau. ee – typeElements est le type des ´l´ments qui vont ˆtre stock´s dans le tableau, il peut s’agir de n’importe quel ee e e type. Par exemple, cr´ons un type tableau de nombres indic´ de 1 ` 10, que nous appelerons numberTab e e a TYPE numberTab IS VARRAY ( 1 0 ) OF N M E U B R; D´claration d’un tableau e Dor´navant, le type d’un tableau peut ˆtre utilis´ au mˆme titre que NUMBER ou VARCHAR2. Par exemple, d´clarons e e e e e un tableau appel´ t de type numberTab, e DECLARE TYPE numberTab IS VARRAY ( 1 0 ) OF N M E U B R; t numberTab ; BEGIN /∗ i n s t r u c t i o n s ∗/ END; / Allocation d’un tableau La cr´ation d’un type tableau met ` disposition un constructeur du mˆme nom que le type cr´´. Cette fonction e a e ee r´serve de l’espace m´moire pour ce tableau et retourne l’adresse m´moire de la zone r´serv´e, il s’agit d’une sorte de e e e e e malloc. Si, par exemple, un type tableau numtab a ´t´ cr´e, la fonction numtab() retourne une tableau vide. ee e DECLARE TYPE numberTab IS VARRAY ( 1 0 ) OF N M E U B R; t numberTab ; BEGIN t := numberTab ( ) ; /∗ u t i l i s a t i o n du t a b l e a u ∗/ END; / Une fois cette allocation faite, il devient presque possible d’utiliser le tableau... Dimensionnement d’un tableau Le tableau retourn´ par le constructeur est vide. Il convient ensuite de r´server de l’espace pour stocker les ´l´ments e e ee qu’il va contenir. On utilise pour cela la m´thode EXTEND(). EXTEND s’invoque en utilisant la notation point´e. Par e e exemple, DECLARE TYPE numberTab IS VARRAY ( 1 0 ) OF N M E U B R; t numberTab ; BEGIN t := numberTab ( ) ; t . EXTEND ( 4 ) ; /∗ u t i l i s a t i o n du t a b l e a u ∗/ END; / 5
  • 7. Dans cet exemple, t.EXTEND(4) ; permet par la suite d’utiliser les ´l´ments du tableau t(1), t(2), t(3) et t(4). ee Il n’est pas possible ”d’´tendre” un tableau ` une taille sup´rieure ` celle sp´cifi´e lors de la cr´ation du type tableau e a e a e e e associ´. e Utilisation d’un tableau On acc`de, en lecture et en ´criture, au i-`me ´l´ment d’une variable tabulaire nomm´ T avec l’instruction T(i). e e e ee e Les ´l´ments sont indic´s ` partir de 1. ee e a Effectuons, par exemple, une permutation circulaire vers la droite des ´l´ments du tableau t. ee DECLARE TYPE numberTab IS VARRAY ( 1 0 ) OF N M E U B R; t numberTab ; i number ; k number ; BEGIN t := numberTab ( ) ; t . EXTEND ( 1 0 ) ; FOR i IN 1 . . 1 0 LOOP t ( i ) := i ; END LOOP ; k := t ( 1 0 ) ; FOR i in REVERSE 2 . . 1 0 LOOP t ( i ) := t ( i − 1 ) ; END LOOP ; t ( 1 ) := k ; FOR i IN 1 . . 1 0 LOOP DBMS_OUTPUT . PUT_LINE ( t ( i ) ) ; END LOOP ; END; / 1.2.2 Structures Un structure est un type regroupant plusieurs types. Une variable de type structur´ contient plusieurs variables, e ces variables s’appellent aussi des champs. Cr´ation d’un type structur´ e e On d´finit un type structur´ de la sorte : e e TYPE /∗ nomType ∗/ IS RECORD ( /∗ l i s t e d e s champs ∗/ ); nomType est le nom du type structur´ construit avec la syntaxe pr´c´dente. La liste suit la mˆme syntaxe que la e e e e liste des colonnes d’une table dans un CREATE TABLE. Par exemple, construisons le type point (dans IR2 ), TYPE point IS RECORD ( abscisse N M E , U BR ordonnee N M E U BR ); Notez bien que les types servant ` d´finir un type structur´ peuvent ˆtre quelconques : variables scalaires, tableaux, a e e e structures, etc. D´claration d’une variable de type structur´ e e point est maintenant un type, il devient donc possible de cr´er des variables de type point, la r`gle est toujours la e e mˆme pour d´clarer des variables en PL/SQL, par exemple e e 6
  • 8. p point ; permet de d´clarer une variable p de type point. e Utilisation d’une variable de type structur´ e Pour acc´der ` un champ d’une variable de type structur´, en lecture ou en ´criture, on utilise la notation point´e : e a e e e v.c est le champ appel´ c de la variable structur´ appel´e v. Par exemple, e e e DECLARE TYPE point IS RECORD ( abscisse N M E , U BR ordonnee N M E U BR ); p point ; BEGIN p . abscisse := 1 ; p . ordonnee := 3 ; DBMS_OUTPUT . PUT_LINE ( ’ p . a b s c i s s e = ’ | | p . abscisse | | ’ and p . ordonnee = ’ | | p . ordonnee ) ; END; / Le script ci-dessous cr´e le type point, puis cr´e une variable t de type point, et enfin affecte aux champs abscisse e e et ordonnee du point p les valeurs 1 et 3. 7
  • 9. 1.3 Utilisation du PL/SQL Ce cours est une introduction aux interactions possibles entre la base de donn´es et les scripts PL/SQL. e 1.3.1 Affectation On place dans une variable le r´sultat d’une requˆte en utilisant le mot-cl´ INTO. Les instructions e e e SELECT champ_1 , . . . , champ_n INTO v_1 , . . . , v_n F O ... R M affecte aux variables v 1, ..., v n les valeurs retourn´es par la requˆte. Par exemple e e DECLARE num N M E U B R; nom V R H R 3 0 ) := ’ Poup´ e Batman ’ ; A C A 2( e BEGIN SELECT numprod INTO num F O PRODUIT R M W E E nomprod = nom ; HR DBMS_OUTPUT . PUT_LINE ( ’L ’ ’ a r t i c l e ’ | | nom | | ’ a pour num´ro ’ | | num ) ; e END; / Prˆtez attention au fait que la requˆte doit retourner une et une une seule ligne, sinon, une erreur se produit ` e e a l’ex´cution. e 1.3.2 Tables et structures Si vous ne tenez pas ` vous prendre la tˆte pour choisir le type de chaque variable, demandez-vous ce que vous a e allez mettre dedans ! Si vous tenez ` y mettre une valeur qui se trouve dans une colonne d’une table, il est possible de a vous r´f´rer directement au type de cette colonne avec le type nomTable.nomColonne%type. Par exemple, ee DECLARE num PRODUIT . numprod%type ; nom PRODUIT . nomprod%type := ’ Poup´ e Batman ’ ; e BEGIN SELECT numprod INTO num F O PRODUIT R M W E E nomprod = nom ; HR DBMS_OUTPUT . PUT_LINE ( ’L ’ ’ a r t i c l e ’ | | nom | | ’ a pour num´ro ’ | | num ) ; e END; / Pour aller plus loin, il est mˆme possible de d´clarer une structure pour repr´senter une ligne d’une table, le type e e e porte alors le nom suivant : nomTable%rowtype. DECLARE nom PRODUIT . nomprod%type := ’ Poup´ e Batman ’ ; e ligne PRODUIT%rowtype ; BEGIN SELECT ∗ INTO ligne F O PRODUIT R M W E E nomprod = nom ; HR DBMS_OUTPUT . PUT_LINE ( ’L ’ ’ a r t i c l e ’ | | ligne . nomprod | | ’ a pour num´ro ’ | | ligne . numprod ) ; e END; / 8
  • 10. 1.3.3 Transactions Un des m´canismes les plus puissants des SGBD r´cents r´side dans le syst`me des transactions. Une transaction e e e e est un ensemble d’op´rations “atomiques”, c’est-`-dire indivisible. Nous consid´rerons qu’un ensemble d’op´rations est e a e e indivisible si une ex´cution partielle de ces instructions poserait des probl`mes d’int´grit´ dans la base de donn´es. e e e e e Par exemple, dans le cas d’une base de donn´es de gestion de comptes en banque, un virement d’un compte ` un autre e a se fait en deux temps : cr´diter un compte d’une somme s, et d´biter un autre de la mˆme somme s. Si une erreur e e e survient pendant la deuxi`me op´ration, et que la transaction est interrompue, le virement est incomplet et le patron e e va vous assassiner. Il convient donc de disposer d’un m´canisme permettant de se prot´ger de ce genre de d´sagr´ment. Plutˆt que e e e e o se casser la tˆte ` tester les erreurs ` chaque ´tape et ` balancer des instructions permettant de “revenir en arri`re”, e a a e a e nous allons utiliser les instructions COMMIT et ROLLBACK. Voici le squelette d’un exemple : /∗ i n s t r u c t i o n s ∗/ IF /∗ e r r e u r ∗/ THEN ROLLBACK; ELSE C M I O MT; END; Le ROLLBACK annule toutes les modifications faites depuis le d´but de la transaction (donc depuis le pr´c´dent e e e COMMIT), COMMIT les enregistre d´finitivement dans la base de donn´es. e e La variable d’environnement AUTOCOMMIT, qui peut ˆtre positionn´e ` ON ou ` OFF permet d’activer la gestion des e e a a transactions. Si elle est positionn´e ` ON, chaque instruction a des r´percussions imm´diates dans la base, sinon, les e a e e modifications ne sont effectives qu’une fois qu’un COMMIT a ´t´ ex´cut´. ee e e 9
  • 11. 1.4 Exceptions Le m´canisme des exceptions est impl´ment´ dans la plupart des langages r´cent, notament orient´s objet. Cette e e e e e fa¸on de programmer a quelques avantages imm´diats : c e – obliger les programmeurs ` traiter les erreurs : combien de fois votre prof de C a hurl´ en vous suppliant a e de v´rifier les valeurs retourn´es par un malloc, ou un fopen ? La plupart des compilateurs des langages ` e e a exceptions (notamment java) ne compilent que si pour chaque erreur potentielle, vous avez pr´par´ un bloc de e e code (´ventuellement vide...) pour la traiter. Le but est de vous assurer que vous n’avez pas oubli´ d’erreur. e e – Rattraper les erreurs en cours d’ex´cution : Si vous programmez un syst`me de s´curit´ de centrale e e e e nucl´aire ou un pilote automatique pour l’aviation civile, une erreur de m´moire qui vous afficherait l’´cran e e e bleu de windows, ou le message “Envoyer le rapport d’erreur ?”, ou plus simplement le fameux “Segmentation fault” produirait un effet des plus mauvais. Certaines erreurs d’´xecution sont rattrapables, autrement dit, il est e possible de r´soudre le probl`me sans interrompre le programme. e e – Ecrire le traitement des erreurs ` part : Pour des raisons fiabilit´, de lisibilit´, il a ´t´ consid´r´ que a e e ee ee m´langer le code “normal” et le traitement des erreurs ´tait un style de programmation perfectible... Dans les e e langages ` exception, les erreurs sont trait´es ` part. a e a 1.4.1 Rattraper une exception Je vous ai menti dans le premier cours, un bloc en PL/SQL a la forme suivante : DECLARE /∗ d e c l a r a t i o n s ∗/ BEGIN /∗ i n s t r u c t i o n s ∗/ EXCEPTION /∗ t r a i t e m e n t d e s e r r e u r s ∗/ END; Une exception est une “erreur type”, elle porte un nom, au mˆme titre qu’une variable a une identificateur, par e exemple GLUBARF. Lorsque dans les instructions, l’erreur GLUBARF se produit, le code du BEGIN s’interrompt et le code de la section EXCEPTION est lanc´. On dit aussi que quand une exception est lev´e (raised) (on dit aussi jet´e e e e (thrown)), on la rattrape (catch) dans le bloc EXCEPTION. La section EXCEPTION a la forme suivante : EXCEPTION W E E1 THEN HN /∗ t r a i t e m e n t ∗/ W E E2 THEN HN /∗ t r a i t e m e n t ∗/ W E E3 THEN HN /∗ t r a i t e m e n t ∗/ W E OTHERS THEN HN /∗ t r a i t e m e n t ∗/ END; On ´num`re les erreurs les plus pertinentes en utilisant leur nom et en consacrant ` chacune d’elle un traitement e e a particulier pour rattraper (ou propager) l’erreur. Quand un bloc est trait´, les WHEN suivants ne sont pas ´valu´s. e e e OTHERS est l’exception par d´faut, OTHERS est toujours v´rifi´, sauf si un cas pr´c´dent a ´t´ v´rifi´. Dans l’exemple e e e e e ee e e suivant : DECLARE /∗ d e c l a r a t i o n s ∗/ BEGIN /∗ i n s t r u c t i o n s ∗/ C M I O MT; EXCEPTION W E GLUBARF THEN HN ROLLBACK; DBMS_OUTPUT . PUT_LINE ( ’GLUBARF e x c e p t i o n r a i s e d ! ’ ) ; W E OTHERS THEN HN DBMS_OUTPUT . PUT_LINE ( ’SQLCODE = ’ | | SQLCODE ) ; DBMS_OUTPUT . PUT_LINE ( ’SQLERRM = ’ | | SQLERRM ) ; 10
  • 12. END; Les deux variables globales SQLCODE et SQLERRM contiennent respectivement le code d’erreur Oracle et un message d’erreur correspondant ` la derni`re exception lev´e. Chaque exception a donc, en plus d’un nom, un code et un a e e message. 1.4.2 Exceptions pr´d´finies e e Bon nombre d’exceptions sont pr´d´finies par Oracle, par exemple e e – NO DATA FOUND est lev´e quand la requˆte d’une instruction de la forme SELECT ... INTO ... ne retourne e e aucune ligne – TOO MANY ROWS est lev´e quand la requˆte d’une instruction de la forme SELECT ... INTO ... retourne plusieurs e e lignes – DUP VAL ON INDEX est lev´e si une insertion (ou une modification) est refus´e ` cause d’une contrainte d’unicit´. e e a e On peut enrichir notre exemple de la sorte : DECLARE num N M E U B R; nom V R H R 3 0 ) := ’ Poup´ e Batman ’ ; A C A 2( e BEGIN SELECT numprod INTO num F O PRODUIT R M W E E nomprod = nom ; HR DBMS_OUTPUT . PUT_LINE ( ’L ’ ’ a r t i c l e ’ | | nom | | ’ a pour num´ro ’ | | num ) ; e EXCEPTION W E NO_DATA_FOUND THEN HN DBMS_OUTPUT . PUT_LINE ( ’ Aucun a r t i c l e ne p o r t e l e nom ’ | | nom ) ; W E TOO_MANY_ROWS THEN HN DBMS_OUTPUT . PUT_LINE ( ’ P l u s i e u r s a r t i c l e s p o r t e n t l e nom ’ | | nom ) ; W E OTHERS THEN HN DBMS_OUTPUT . PUT_LINE ( ’ I l y a un g r o s p r o b l` m e . . . ’ ) ; e END; / SELECT numprod INTO num... l`ve une exception si la requˆte renvoie un nombre de lignes diff´rent de 1. e e e 1.4.3 Codes d’erreur Je vous encore menti, certaines exceptions n’ont pas de nom. Elle ont seulement un code d’erreur, il est conseill´ e de se reporter ` la documentation pour les obtenir. On les traite de la fa¸on suivante a c EXCEPTION W E OTHERS THEN HN IF SQLCODE = CODE1 THEN /∗ t r a i t e m e n t ∗/ ELSIF SQLCODE = CODE2 THEN /∗ t r a i t e m e n t ∗/ ELSE DBMS_OUTPUT . PUT_LINE ( ’ J ’ ’ v o i s pas c ’ ’ que ca peut et re . . . ’ ) ; END; C’est souvent le cas lors de violation de contraintes. 1.4.4 D´clarer et lancer ses propres exceptions e Exception est un type, on d´clare donc les exceptions dans une section DECLARE. Une exception se lance avec e l’instruction RAISE. Par exemple, 11
  • 13. DECLARE GLUBARF EXCEPTION; BEGIN RAISE GLUBARF ; EXCEPTION W E GLUBARF THEN HN DBMS_OUTPUT . PUT_LINE ( ’ g l u b a r f r a i s e d . ’ ) ; END; / 12
  • 14. 1.5 Sous-programmes 1.5.1 Proc´dures e Syntaxe On d´finit une proc´dure de la sorte e e CREATE OR REPLACE PROCEDURE /∗ nom ∗/ ( /∗ p a r a m e t r e s ∗/ ) IS /∗ d e c l a r a t i o n d e s v a r i a b l e s l o c a l e s ∗/ BEGIN /∗ i n s t r u c t i o n s ∗/ END; les param`tres sont une simple liste de couples nom type. Par exemple, la procedure suivante affiche un compte ` e a rebours. CREATE OR REPLACE PROCEDURE compteARebours ( n N M E U B R) IS BEGIN IF n >= 0 THEN DBMS_OUTPUT . PUT_LINE ( n ) ; compteARebours ( n − 1 ) ; END IF ; END; Invocation En PL/SQL, une proc´dure s’invoque tout simplement avec son nom. Mais sous SQL+, on doit utiliser le mot-cl´ e e CALL. Par exemple, on invoque le compte ` rebours sous SQL+ avec la commande CALL compteARebours(20). a Passage de param`tres e Oracle permet le passage de param`tres par r´f´rence. Il existe trois types de passage de param`tres : e ee e – IN : passage par valeur – OUT : aucune valeur pass´e, sert de valeur de retour e – IN OUT : passage de param`tre par r´f´rence e ee Par d´faut, le passage de param`tre se fait de type IN. e e CREATE OR REPLACE PROCEDURE incr ( val IN OUT N M E U B R) IS BEGIN val := val + 1 ; END; 1.5.2 Fonctions Syntaxe On cr´e une nouvelle fonction de la fa¸on suivante : e c CREATE OR REPLACE FUNCTION /∗ nom ∗/ ( /∗ p a r a m e t r e s ∗/ ) RETURN /∗ t y p e ∗/ IS /∗ d e c l a r a t i o n d e s v a r i a b l e s l o c a l e s ∗/ BEGIN /∗ i n s t r u c t i o n s ∗/ END; L’instruction RETURN sert ` retourner une valeur. Par exemple, a CREATE OR REPLACE FUNCTION module ( a N M E , b N M E U BR U B R) RETURN N M E IS U BR BEGIN IF a < b THEN RETURN a ; ELSE 13
  • 15. RETURN module ( a − b , b ) ; END IF ; END; Invocation Tout comme les proc´dures, l’invocation des fonctions ne pose aucun probl`me en PL/SQL, par contre, sous SQL+, e e c’est quelque peu particulier. On passe par une pseudo-table nomm´e DUAL de la fa¸on suivante : e c SELECT module ( 2 1 , 1 2 ) F O DUAL ; R M Passage de param`tres e Les param`tres sont toujours pass´s avec le type IN. e e 14
  • 16. 1.6 Curseurs 1.6.1 Introduction Les instructions de type SELECT ... INTO ... manquent de souplesse, elles ne fontionnent que sur des requˆtes e retourant une et une seule valeur. Ne serait-il pas int´ressant de pouvoir placer dans des variables le r´sultat d’une e e requˆte retournant plusieurs lignes ? A m´diter... e e 1.6.2 Les curseurs Un curseur est un objet contenant le r´sultat d’une requˆte (0, 1 ou plusieurs lignes). e e d´claration e Un curseur se d´clare dans une section DECLARE : e CURSOR /∗ nomcurseur ∗/ IS /∗ r e q u ˆ t e ∗/ ; e Par exemple, si on tient ` r´cup´rer tous les employ´s de la table EMP, on d´clare le curseur suivant. a e e e e CURSOR emp_cur IS SELECT ∗ F O EMP ; R M Ouverture Lors de l’ouverture d’un curseur, la requˆte du curseur est ´valu´e, et le curseur contient toutes les donn´es e e e e retourn´es par la requˆte. On ouvre un curseur dans une section BEGIN : e e OPEN /∗ nomcurseur ∗/ ; Par exemmple, DECLARE CURSOR emp_cur IS SELECT ∗ F O EMP ; R M BEGIN OPEN emp_cur ; /∗ U t i l i s a t i o n du c u r s e u r ∗/ END; Lecture d’une ligne Une fois ouvert, le curseur contient toutes les lignes du r´sultat de la requˆte On les r´cup`re une par une en e e e e utilisant le mot-cl´ FETCH : e FETCH /∗ nom curseur ∗/ INTO /∗ l i s t e v a r i a b l e s ∗/ ; La liste de variables peut ˆtre remplac´e par une structure de type nom curseur%ROWTYPE. Si la lecture de la ligne e e ´choue, parce qu’il n’y a plus de ligne ` lire, l’attribut %NOTFOUND prend la valeur vrai. e a DECLARE CURSOR emp_cur IS SELECT ∗ F O EMP ; R M ligne emp_cur%rowtype BEGIN OPEN emp_cur ; LOOP FETCH emp_cur INTO ligne ; EXIT W E emp_cur%NOTFOUND ; HN DBMS_OUTPUT . PUT_LINE ( ligne . ename ) ; END LOOP ; /∗ . . . ∗/ END; 15
  • 17. Fermeture Apr`s utilisation, il convient de fermer le curseur. e CLOSE /∗ nomcurseur ∗/ ; Compl´tons notre exemple, e DECLARE CURSOR emp_cur IS SELECT ∗ F O EMP ; R M ligne emp_cur%rowtype ; BEGIN OPEN emp_cur ; LOOP FETCH emp_cur INTO ligne ; EXIT W E emp_cur%NOTFOUND ; HN DBMS_OUTPUT . PUT_LINE ( ligne . ename ) ; END LOOP ; CLOSE emp_cur ; END; / Le programme ci-dessus peut aussi s’´crire e DECLARE CURSOR emp_cur IS SELECT ∗ F O EMP ; R M ligne emp_cur%rowtype ; BEGIN OPEN emp_cur ; FETCH emp_cur INTO ligne ; WHILE emp_cur%FOUND LOOP DBMS_OUTPUT . PUT_LINE ( ligne . ename ) ; FETCH emp_cur INTO ligne ; END LOOP ; CLOSE emp_cur ; END; Boucle FOR Il existe une boucle FOR se chargeant de l’ouverture, de la lecture des lignes du curseur et de sa fermeture, FOR ligne IN emp_cur LOOP /∗ Traitement ∗/ END LOOP ; Par exemple, DECLARE CURSOR emp_cur IS SELECT ∗ F O EMP ; R M ligne emp_cur%rowtype ; BEGIN FOR ligne IN emp_cur LOOP DBMS_OUTPUT . PUT_LINE ( ligne . ename ) ; END LOOP ; END; / 16
  • 18. 1.7 Curseurs parametr´s e 1.7.1 Introduction A votre avis, le code suivant est-il valide ? DECLARE N M E n := 1 4 ; U BR BEGIN DECLARE CURSOR C IS SELECT ∗ F O PERSONNE R M W E E numpers >= n ; HR ROW C%rowType ; BEGIN FOR ROW IN C LOOP DBMS_OUTPUT . PUT_LINE ( ROW . numpers ) ; END LOOP ; END; END; / R´ponse : non. La requˆte d’un curseur ne peut pas contenir de variables dont les valeurs ne sont pas fix´es. e e e Pourquoi ? Parce que les valeurs des ces sont susceptibles de changer entre la d´claration du curseur et son ouverture. e Le rem`de est un curseur param´tr´. e e e 1.7.2 D´finition e Un curseur param´tr´ est un curseur dont la requˆte contient des variables dont les valeurs ne seront fix´es qu’` e e e e a l’ouverture. 1.7.3 D´claration e On pr´cise la liste des noms et des type des param`tres entre parenth`ses apr`s le nom du curseur : e e e e CURSOR /∗ nom ∗/ ( /∗ l i s t e d e s p a r a m` t r e s ∗/ ) IS e /∗ r e q u ˆ t e ∗/ e Par exemple, cr´eons une requˆte qui, pour une personne donn´e, nous donne la liste des noms et pr´noms de ses e e e e enfants : CURSOR enfants ( numparent N M E U B R) IS SELECT ∗ F O PERSONNE R M W E E pere = numparent HR OR mere = numparent ; 1.7.4 Ouverture On ouvre un curseur param´tr´ en passant en param`tre les valeurs des variables : e e e OPEN /∗ nom ∗/ ( /∗ l i s t e d e s p a r a m` t r e s ∗/ ) e Par exemple, OPEN enfants ( 1 ) ; 1.7.5 Lecture d’une ligne, fermeture la lecture d’une ligne suit les mˆmes r`gles qu’avec un curseur non param´tr´. e e e e 17
  • 19. 1.7.6 Boucle pour La boucle pour se charge de l’ouverture, il convient donc de placer les param`tre dans l’entˆte de la boucle, e e FOR /∗ v a r i a b l e ∗/ IN /∗ nom ∗/ ( /∗ l i s t e p a r a m` t r e s ∗/ ) LOOP e /∗ i n s t r u c t i o n s ∗/ END LOOP ; Par exemple, FOR e IN enfants ( 1 ) LOOP DBMS_OUTPUT . PUT_LINE ( e . nompers | | ’ ’ | | e . prenompers ) ; END LOOP ; 1.7.7 Exemple r´capitulatif e DECLARE CURSOR parent IS SELECT ∗ F O PERSONNE ; R M p parent%rowtype ; CURSOR enfants ( numparent N M E U B R) IS SELECT ∗ F O PERSONNE R M W E E pere = numparent HR OR mere = numparent ; e enfants%rowtype ; BEGIN FOR p IN parent LOOP DBMS_OUTPUT . PUT_LINE ( ’ Les e n f a n t s de ’ | | p . prenom | | ’ ’ | | p . nom | | ’ s o n t : ’ ) ; FOR e IN enfants ( p . numpers ) LOOP DBMS_OUTPUT . PUT_LINE ( ’ ∗ ’ | | e . prenom | | ’ ’ | | e . nom ); END LOOP ; END LOOP ; END; / 18
  • 20. 1.8 Triggers 1.8.1 Principe Un trigger est une proc´dure stock´e qui se lance automatiquement lorsqu’un ´v´nement se produit. Par ´v´nement, e e e e e e on entend dans ce cours toute modification des donn´es se trouvant dans les tables. On s’en sert pour contrˆler ou e o appliquer des contraintes qu’il est impossible de formuler de fa¸on d´clarative. c e 1.8.2 Classification Type d’´v´nement e e Lors de la cr´ation d’un trigger, il convient de pr´ciser quel est le type d’´v´nement qui le d´clenche. Nous r´aliserons e e e e e e dans ce cours des triggers pour les ´v´nements suivants : e e – INSERT – DELETE – UPDATE Moment de l’´xecution e On pr´cise aussi si le trigger doit ˆtre ´xecut´ avant (BEFORE) ou apr`s (AFTER) l’´v´nement. e e e e e e e Ev´nements non atomiques e Lors que l’on fait un DELETE ..., il y a une seule instruction, mais plusieurs lignes sont affect´es. Le trigger doit-il e ˆtre ex´cut´ pour chaque ligne affect´e (FOR EACH ROW), ou seulement une fois pour toute l’instruction (STATEMENT) ? e e e e – un FOR EACH ROW TRIGGER est ex´cut´ ` chaque fois qu’une ligne est affect´e. e ea e – un STATEMENT TRIGGER est ´xecut´e ` chaque fois qu’une instruction est lanc´e. e e a e 1.8.3 Cr´ation e Syntaxe On d´clare un trigger avec l’instruction suivante : e CREATE OR REPLACE TRIGGER nomtrigger [ BEFORE | AFTER ] [INSERT | DELETE | UPDATE] ON nomtable [ FOR EACH ROW | ] DECLARE /∗ d e c l a r a t i o n s ∗/ BEGIN /∗ i n s t r u c t i o n s ∗/ END; Par exemple, SQL> CREATE OR REPLACE TRIGGER pasDeDeleteDansClient 2 BEFORE DELETE ON CLIENT 3 BEGIN 4 RAISE_APPLICATION_ERROR ( −20555 , ’Va t e f a i r e . . . ’ ) ; 5 END; 6 / D´ clencheur cr´ ´ . e ee SQL> SELECT C U T( ∗ ) O N 2 F O CLIENT ; R M C U T( ∗ ) O N −−−−−−−−−− 21 SQL> DELETE F O CLIENT ; R M 19
  • 21. DELETE F O CLIENT R M ∗ ERREUR ` la ligne 1 : a ORA −20555: Va te faire . . . ORA −06512: ` ”SCOTT.PASDEDELETEDANSCLIENT” , ligne 2 a ORA −04088: erreur lors d ex´ cution du d´ clencheur ’SCOTT.PASDEDELETEDANSCLIENT ’ e e SQL> SELECT C U T( ∗ ) O N 2 F O CLIENT ; R M C U T( ∗ ) O N −−−−−−−−−− 21 L’instruction RAISE APPLICATION ERROR(code, message) l`ve une exception sans nom portant un code code et e un message d’erreur message. Vous remarquez que comme l’erreur a ´t´ lev´e avant la suppression, les donn´es sont ee e e toujours pr´sentes dans la table CLIENT. Le trigger a contrˆl´ une r`gle, et comme elle n’´tait pas respect´e, il a lanc´ e oe e e e e une erreur. Combinaisons d’´v´nements e e Il est possible, en s´parant les types d’´v´nement par le mot-cl´ OR, de d´finir un trigger d´clench´ par plusieurs e e e e e e e ´v´nements. Les variables bool´ennes INSERTING, UPDATING et DELETING permettent d’identifier l’´v´nement qui a e e e e e d´clench´ le trigger. e e CREATE OR REPLACE TRIGGER afficheEvenement BEFORE INSERT OR UPDATE OR DELETE ON CLIENT FOR EACH ROW BEGIN IF INSERTING THEN DBMS_OUTPUT . PUT_LINE ( ’ I n s e r t i o n dans CLIENT ’ ) ; ELSIF UPDATING THEN DBMS_OUTPUT . PUT_LINE ( ’ Mise a j o u r dans CLIENT ’ ) ; ELSE DBMS_OUTPUT . PUT_LINE ( ’ S u p p r e s s i o n dans CLIENT ’ ) ; END IF ; END; 1.8.4 Acc`s aux lignes en cours de modification e Dans les FOR EACH ROW triggers, il est possible avant la modification de chaque ligne, de lire l’ancienne ligne et la nouvelle ligne par l’interm´diaire des deux variables structur´es :old et :new. Par exemple le trigger suivant empˆche e e e de diminuer un salaire : CREATE OR REPLACE TRIGGER pasDeBaisseDeSalaire BEFORE UPDATE ON EMP FOR EACH ROW BEGIN IF ( : old . sal > : new . sal ) THEN RAISE_APPLICATION_ERROR ( −20567 , ’ Pas de b a i s s e de s a l a i r e ! ’ ) ; END IF ; END; Tables en mutation Il est impossible, dans un trigger de type FOR EACH ROW de faire un SELECT sur la table en cours de modification. 20
  • 22. SQL> CREATE OR REPLACE TRIGGER beforeStatement 2 BEFORE UPDATE ON CLIENT 3 DECLARE 4 NB N M E U B R; 5 BEGIN 6 SELECT C U T( ∗ ) INTO NB O N 7 F O CLIENT ; R M 8 END; 9 / D´ clencheur cr´ ´ . e ee SQL> SQL> CREATE OR REPLACE TRIGGER afterStatement 2 AFTER UPDATE ON CLIENT 3 DECLARE 4 NB N M E U B R; 5 BEGIN 6 SELECT C U T( ∗ ) INTO NB O N 7 F O CLIENT ; R M 8 END; 9 / D´ clencheur cr´ ´ . e ee SQL> SQL> UPDATE CLIENT SET nomcli = nomcli ; 21 ligne ( s ) mise ( s ) ` jour . a SQL> SQL> CREATE OR REPLACE TRIGGER beforeForEachRow 2 BEFORE UPDATE ON CLIENT 3 FOR EACH ROW 4 DECLARE 5 NB N M E U B R; 6 BEGIN 7 SELECT C U T( ∗ ) INTO NB O N 8 F O CLIENT ; R M 9 END; 10 / D´ clencheur cr´ ´ . e ee SQL> SQL> UPDATE CLIENT SET nomcli = nomcli ; UPDATE CLIENT SET nomcli = nomcli ∗ ERREUR ` la ligne 1 : a ORA −04091: la table SCOTT . CLIENT est en mutation ; le d´ clencheur ou la e fonction ne peut la voir ORA −06512: ` ”SCOTT.BEFOREFOREACHROW” , ligne 4 a ORA −04088: erreur lors d ex´ cution du d´ clencheur ’SCOTT.BEFOREFOREACHROW’ e e SQL> DROP TRIGGER beforeForEachRow ; D´ clencheur supprim´ . e e 21
  • 23. SQL> SQL> SQL> CREATE OR REPLACE TRIGGER afterForEachRow 2 AFTER UPDATE ON CLIENT 3 FOR EACH ROW 4 DECLARE 5 NB N M E U B R; 6 BEGIN 7 SELECT C U T( ∗ ) INTO NB O N 8 F O CLIENT ; R M 9 END; 10 / D´ clencheur cr´ ´ . e ee SQL> SQL> UPDATE CLIENT SET nomcli = nomcli ; UPDATE CLIENT SET nomcli = nomcli ∗ ERREUR ` la ligne 1 : a ORA −04091: la table SCOTT . CLIENT est en mutation ; le d´ clencheur ou la e fonction ne peut la voir ORA −06512: ` ”SCOTT.AFTERFOREACHROW” , ligne 4 a ORA −04088: erreur lors d ex´ cution du d´ clencheur ’SCOTT.AFTERFOREACHROW’ e e 1.8.5 Contourner le probl`me des tables en mutation e Il existe plusieurs fa¸ons de contourner ce probl`me : c e – Utiliser un STATEMENT trigger. Comme on ne sait pas quelles lignes ont ´t´ modifi´es, on est oblig´ de toutes ee e e les traiter. Cette approche pr´sente donc un inconv´nient majeur : elle nous am`ne ` effectuer de nombreux e e e a traitements inutiles. – En ayant des donn´es redondantes. Il suffit que les donn´es servant ` la v´rification se trouvent dans une autre e e a e table que celle en mutation. Cette m´thode a pour inconv´nient la m´moire occup´e et la quantit´ de code ` ´crire e e e e e ae pour maintenir la coh´rence des donn´es. Dans la plupart des cas, cette solution est malgr´ tout la meilleure. e e e Colonnes suppl´mentaires e Par exemple, si l’on souhaite empˆcher un client d’avoir plus de 10 comptes en banque, une solution est de placer e dans la table client une colonne contenant le nombre de comptes. ALTER TABLE CLIENT A D nbComptes number ; D UPDATE CLIENT SET nbComptes = 0 ; Une fois cette table cr´e, il convient de s’assurer que les donn´es de la colonne nbComptes contient toujours les e e bonnes valeurs. On le fait avec plusieurs sous-programmes : CREATE OR REPLACE TRIGGER metAJourNbComptes AFTER INSERT OR UPDATE OR DELETE ON COMPTECLIENT BEGIN UPDATE CLIENT SET nbComptes = ( SELECT C U T( ∗ ) O N F O COMPTECLIENT CC R M W E E CC . numCli = numCli HR ); END; / CREATE OR REPLACE TRIGGER verifieNbComptes 22
  • 24. BEFORE INSERT ON COMPTECLIENT FOR EACH ROW DECLARE nbComptes N M E U B R; BEGIN SELECT nbComptes INTO nbComptes F O CLIENT R M W E E numCli = : new . numcli ; HR IF ( nbComptes >= 1 0 ) THEN RAISE_APPLICATION_ERROR ( −20556 , ’ Ce c l i e n t a d e j a t r o p de comptes ’ ) ; END IF ; END; / On peut affiner en rempla¸ant metAJourNbComptes par plusieurs sous-programmes : c CREATE OR REPLACE TRIGGER initialiseNbComptes BEFORE INSERT ON CLIENT FOR EACH ROW BEGIN : new . nbComptes := 0 ; END; / CREATE OR REPLACE TRIGGER metAJourNbComptes AFTER INSERT OR UPDATE OR DELETE ON COMPTECLIENT FOR EACH ROW BEGIN IF DELETING OR UPDATING THEN UPDATE CLIENT SET nbComptes = nbComptes − 1 W E E numcli = : old . numcli ; HR END IF ; IF INSERTING OR UPDATING THEN UPDATE CLIENT SET nbComptes = nbComptes + 1 W E E numcli = : new . numcli ; HR END IF ; END; / Tables suppl´mentaires e Si l’on souhaite par exemple empˆcher les circuits dans la table PERSONNE, il est n´cessaire de faire un parcours e e de graphe. Ce qui n´cessite des SELECT dans la table en cours de mutation. La seule solution est dans ce cas d’avoir e une table miroir qui contient les colonnes cl´s primaire et ´trang`res de cette table, et de s’en servir pour d´tecter les e e e e circuits. CREATE TABLE MIRRORPERSONNE ( numpers N M E PRIMARY KEY, U BR pere N M E , U BR mere N M E U BR ); Nous allons ensuite proc´der de mˆme, en r´percutant chaque op´ration de PERSONNE sur MIRRORPERSONNE. e e e e CREATE OR REPLACE TRIGGER miseAJourMirrorPersonne BEFORE UPDATE OR INSERT OR DELETE ON PERSONNE FOR EACH ROW BEGIN IF DELETING OR UPDATING THEN 23
  • 25. DELETE F O MIRRORPERSONNE R M W E E numpers = : old . numpers ; HR END IF ; IF INSERTING OR UPDATING THEN INSERT INTO MIRRORPERSONNE VALUES ( : new . numpers , : new . pere , : new . mere ) ; END IF ; END; / Une fois cela fait, il suffit de rechercher si une personne ins´r´e est une descendante d’elle mˆme dans MIRRORPERSONNE. ee e CREATE OR REPLACE FUNCTION trouveCircuit ( current N M E , toFind N M E U BR U B R) RETURN BOOLEAN IS numPere N M E U B R; numMere N M E U B R; BEGIN IF ( current IS NULL) THEN RETURN FALSE; END IF ; SELECT pere , mere INTO numPere , numMere F O MIRRORPERSONNE R M W E E numPers = current ; HR RETURN ( numPere = toFind OR numMere = toFind OR trouveCircuit ( numPere , toFind ) OR trouveCircuit ( numMere , toFind ) ) ; END; / CREATE OR REPLACE TRIGGER verifieCircuit AFTER UPDATE OR INSERT ON PERSONNE FOR EACH ROW BEGIN IF ( trouveCircuit ( : new . numPers , : new . numPers ) ) THEN RAISE_APPLICATION_ERROR ( −20557 , ’ C i r c u i t dans l ’ ’ a r b r e g ´ n ´ a l o g i q u e . ’ ) ; e e END IF ; END; / 24
  • 26. 1.9 Packages 1.9.1 Principe Un package est un ensemble de sous-programmes et de variables form´ par e – Une sp´cification : d´claration de variables et de sous-programmes e e – Un corps : impl´mentation des sous-programmes e Tout ce qui se trouve dans la sp´cification doit se trouver dans le corps, mais la r´ciproque est fausse. Un package e e satisfait les points suivants : – encapsulation : certains traitements sont masqu´s, seule la sp´cification du package est visible. Cela a pour e e avantage de simplifier la tˆche de celui qui va utiliser le package. a – modularit´ : il est possible de d´velopper s´par´ment les diverses parties de l’application. le d´veloppement e e e e e devient ainsi un assemblage de package. Ces deux aspects fournissent une souplesse certaine au niveau du d´veloppement : il est possible de modifier le e corps d’un package sans changer sa sp´cification, donc sans modifier le fonctionnement de l’application. e 1.9.2 Sp´cification e La syntaxe permettant de cr´er l’entˆte est la suivante : e e CREATE OR REPLACE PACKAGE nompackage IS /∗ declarations ∗/ END nomPackage ; / Par exemple, CREATE OR REPLACE PACKAGE compteur IS procedure reset ; function nextValue return number ; END compteur ; / 1.9.3 Corps La syntaxe permettant de cr´er le corps est la suivante : e CREATE OR REPLACE PACKAGE BODY nompackage IS /∗ implementation ∗/ END nomPackage ; / Par exemple, CREATE OR REPLACE PACKAGE BODY compteur IS cpt N M E U B R := 0 ; PROCEDURE reset IS BEGIN cpt := 0 ; END; FUNCTION nextValue RETURN N M E IS U BR BEGIN cpt := cpt + 1 ; RETURN cpt − 1 ; END; END compteur ; 25
  • 27. / On peut utiliser un package depuis n’importe quel script PL/SQL : DECLARE nb N M E U B R; BEGIN FOR nb IN 4 . . 2 0 LOOP DBMS_OUTPUT . PUT_LINE ( COMPTEUR . nextValue ( ) ) ; END LOOP ; COMPTEUR . RESET ( ) ; FOR nb IN REVERSE 0 . . 1 0 LOOP DBMS_OUTPUT . PUT_LINE ( COMPTEUR . nextValue ( ) ) ; END LOOP ; END; / 26
  • 28. Chapitre 2 Exercices 2.1 Introduction au PL/SQL Exercice 1 Ecrivez un programme affectant les valeurs 1 et 2 ` deux variables a et b, puis permutant les valeurs de ces deux a variables. Exercice 2 Ecrivez un programme pla¸ant la valeur 10 dans une variable a, puis affichant la factorielle de a. c Exercice 3 Ecrivez un programme pla¸ant les valeurs 48 et 84 dans deux variables a et b puis affichant le pgcd de a et b. c 27
  • 29. 2.2 Tableaux et Structures Exercice 1 1. Cr´ez un type tableau pouvant contenir jusqu’` 50 entiers. e a 2. Cr´ez une variable de ce type , faites une allocation dynamique et dimensionnez ce tableau ` 20 emplacements. e a 3. Placez dans ce tableau la liste des 20 premiers carr´s parfaits : 1, 4, 9, 16, 25, . . . e 4. Inversez l’ordre des ´l´ments du tableau ee 5. Affichez le tableau. Exercice 2 Triez le tableau pr´c´dent avec la m´thode du tri ` bulle. e e e a Exercice 3 Recherchez, par dichotomie, si l’´l´ment 225 se trouve dans le tableau. ee Exercice 4 On impl´mente des listes chaˆ ees avec des tableaux de la sorte, e ın´ SET SERVEROUTPUT ON DECLARE -- Maillon d’une liste cha^n´e ı e TYPE CELL IS RECORD ( -- Donn´e de chaque maillon e data INTEGER, -- Indice du maillon pr´c´dent de la liste, e e -- -1 s’il n’y en a pas previous INTEGER, -- Indice du maillon suivant de la liste, -- -1 s’il n’y en a pas next INTEGER ); -- Type tableau contenant les maillons de la liste TYPE TREE IS VARRAY (19) OF CELL; -- Tableau contenant les maillons de la liste t TREE; -- indice du premier ´l´ment de la liste e e first integer; -- indice du dernier ´l´ment de la liste e e last integer; BEGIN t := TREE(); t.extend(19); -- Initialisation FOR i IN 1..19 LOOP t(i).data := power(i, 5) mod 19 ; t(i).previous := i-1; t(i).next := i+1; END LOOP; first := 1; last := 19; t(first).previous := -1; t(last).next := -1; 28
  • 30. -- Affichage DECLARE p integer := first; BEGIN WHILE p <> -1 LOOP DBMS_OUTPUT.PUT_LINE(’(’ || p || ’, ’ || t(p).data || ’, ’ || t(p).previous || ’, ’ || t(p).next || ’)’); p := t(p).next; END LOOP; END; /* Ecrivez la suite vous-m^me... */ e END; / Inversez l’ordre des ´l´ments de la liste, sans changer les indices des maillons (seulement en modifiant le chaˆ ee ınage). Exercice 5 Utilisez le tri ` bulle pour remettre les ´l´ments dans l’ordre. Les indications sont les mˆmes : ne d´placez pas les a ee e e maillons, vous n’avez le droit de toucher qu’au chaˆınage. Bon courage, l’aspirine n’est pas fournie. 29
  • 31. 2.3 Utilisation PL/SQL Nous travaillerons sur les donn´es A.6 et A.5. e Vous n’oublierez pas de placer des commit en des lieux bien choisis. Exercice 1 Vous remarquerez que les valeurs des numpers de la table PERSONNE forment une s´quence de nombres de 1 ` 21. e a Utilisez une boucle dans laquelle vous placerez une requˆte pour recopier les couples nom/pr´nom de la table personne e e dans la table CLIENT. Exercice 2 Ecrivez un script r´cup´rant le client de cl´ primaire la plus ´lev´e, et injectant ce client dans la table PERSONNEL. e e e e e Exercice 3 Ouvrez un compte courant pour chaque personne, effectuez un d´pˆt en esp`ce ´gal ` numpers ∗ 100 euros. e o e e a Exercice 4 Ouvrez un livret pour chaque personne ayant un numpers pair, faites un virement de leur compte courant vers ce livret de sorte qu’il ne reste plus que 500 sur leur compte. 30
  • 32. 2.4 Exceptions Nous utiliserons les donn´es de A.7 et A.5 e Vous ˆtes invit´s ` modifier le code de la s´ance pr´c´dente. Chaque fois qu’un SELECT ... INTO ... sera effectu´, e e a e e e e vous rattraperez les exceptions NO DATA FOUND et TOO MANY ROWS. A chaque insertion, vous ratrapperez l’exception DUP VAL ON INDEX. Exercice 1 Faites de sorte que les scripts important les donn´es des tables CLIENT ne puissent ˆtre ex´cut´s qu’une seule fois. e e e e Exercice 2 Les scripts remplissant la table Operation ne fonctionneront pas aujourd’hui... Mˆme s’il fonctionnaient la derni`re e e fois. Trouvez les codes d’erreurs des exceptions lev´es par ces scripts, rattrapez-les de la fa¸on la plus appropri´e qui e c e soit. 31
  • 33. 2.5 Sous-programmes Exercice 1 Ecrire une fonction r´cursive retournant bn , avec n entier positif ou nul. e Exercice 2 Am´liorer la fonction pr´c´dente en utilisant le fait que e e e n bn = (b2 ) 2 si n est pair. Pour les questions suivantes, utilisez les donn´es de A.5. e Exercice 3 Ecrire une fonction demi-freres prenant deux num´ros de personnes en param`tre et retournant vrai si et seulement e e si ces deux personnes ont un parent en commun. Exercice 4 Ecrire une fonction cousins germains prenant deux num´ros de personnes en param`tre et retournant vrai si et e e seulement si ces deux deux individus sont cousins germains. Exercice 5 Ecrire une proc´dure r´cursive affichant le nom de la personne dont le num´ro est pass´ en param`tre et se rappellant e e e e e r´cursivement sur le p`re de cette personne. Faites de sorte ` ne pas utiliser d’exceptions. e e a Exercice 6 Ecrire une proc´dure r´cursive affichant les noms des ascendants de sexe masculin de la personne dont le num´ro e e e est pass´ en param`tre. e e Exercice 7 Ecrire une fonction r´cursive prenant deux num´ros de personne A et B et retournant vrai si A est un ascendant e e de B. Exercice 8 Ecrire une fonction prenant en param`tre deux num´ros de personne A et B et retournant, si l’un est un ascendant e e de l’autre, le nombre de g´n´rations les s´parant, −1 si l’un n’est pas un ascendant de l’autre. e e e Exercice 9 Pr´parez un verre d’aspirine et ´crivez une requˆte retournant le(s) couples(s) personnes s´par´es par le plus de e e e e e g´n´rations. e e Exercice 10 Reprendre le code du tp pr´c´dent, le d´couper en sous-programmes de la fa¸on la moins inintelligente possible. e e e c Bon courage. 32
  • 34. 2.6 Curseurs Exercice 1 Refaites les exercices de 2.3 en utilisant les curseurs. Exercice 2 En utlisant les donnees A.5, ecrivez une fonction affichant toute la descendance d’une personne. 33
  • 35. 2.7 Curseurs parametr´s e L’int´rˆt de ces exercices ´tant de vous familiariser avec les curseurs param´tr´s, vous ferez en sorte de ne pas ee e e e contourner leur usage. Nous utiliserons les donn´es de A.6 e Exercice 1 Ecrire une proc´dure qui affiche tous les clients, et pour chaque client, la liste des comptes. e Exercice 2 Ecrire une proc´dure qui affiche tous les clients, et pour chaque client, la liste des comptes, et pour chacun de ces e comptes, l’historique des op´rations. e 34
  • 36. 2.8 Triggers Impl´mentez les contraintes suivantes dans les donn´es de les donn´es de A.8. Vous ferez des sous-programmes e e e tenant sur une page, et ne contenant pas plus de trois niveaux d’imbrication. Vous r´pertorierez les num´ros d’erreurs e e que vous affecterez a chaque lev´e d’exception. ` e 1. Il ne doit pas ˆtre possible de modifier la note min dans la table prerequis. e 2. Dans un module, il ne doit pas y avoir plus de effecMax ´l`ves inscrits. ee 3. On ne peut cr´er un examen pour un module que s’il y a des ´l`ves inscrits dans ce module. e ee 4. Un ´l`ve ne peut passer un examen que si sa date d’inscription est ant´rieure ` la date de l’examen. ee e a 5. Il ne doit pas y avoir de circuit dans la table prerequis (il existe une fa¸on de la v´rifier en PL/SQL, mais c e comme vous ne la connaissez pas, faites un parcours en profondeur du graphe des pr´-requis) e 6. Un ´l`ve s’inscrivant ` un module doit avoir eu au moins la note min ` tous les modules pr´-requis. ee a a e 7. Ajouter dans ´tudiant un champ moyenne, celui-ci contiendra la moyenne de chaque ´tudiant s’il a pass´ les e e e examens de tous les modules dans lesquels il est inscrit. 8. Revenez sur la premi`re contrainte : il ne doit ˆtre possible de modifier une note min dans la table prerequis que e e s’il n’existe pas d’´l`ve dont une inscription serait invalid´e. ee e 9. Il ne doit ˆtre possible de modifier effecMax que si des ´tudiants ne se retrouvent pas avec une inscription e e invalid´e. e Libre ` vous par la suite de trouver d’autres contraintes et de les impl´menter. a e 35
  • 37. 2.9 Packages Exercice 1 Lancez deux sessions simultan´ment sur le mˆme serveur et invoquez les sous-programmes du package compteur e e depuis chacune des sessions. Que remarquez-vous ? Exercice 2 Impl´menter le corps du package suivant (utilisez les donn´es de A.5). e e CREATE OR R E P L A C E P A C K A G E g e s t i o n _ a r b r e I S c i r c u i t exception ; c u r s o r f e u i l l e s r e t u r n p e r s o n n e%r o w t y p e ; p r o c e d u r e a j o u t e P e r s o n n e ( n o m p e r s o n n e . n o m%t y p e , p r e n o m p e r s o n n e . p r e n o m%t y p e , p e r e p e r s o n n e . p e r e%t y p e , m e r e p e r s o n n e . m e r e%t y p e ) ; p r o c e d u r e m o d i f i e P a r e n t s ( p e r s p e r s o n n e . n u m p e r s%t y p e , n u m P e r e p e r s o n n e . p e r e%t y p e , n u m M e r e p e r s o n n e . m e r e%t y p e ) ; END g e s t i o n _ a r b r e ; / 36
  • 38. 2.10 R´visions e Impl´mentez les contraintes suivantes dans les donn´es de A.9. e e 1. Les parents d’une mˆme personne sont des personnes diff´rentes. e e 2. L’arbre g´n´alogique ne contient pas de circuit. e e 3. Les dates de divorce sont ult´rieures aux dates de mariage. e 4. Une mˆme personne ne peut pas ˆtre mari´e ` plusieurs personnes simultan´ment. e e e a e 5. Personne ne peut ˆtre p`re d’une personne et m`re d’une autre. e e e 6. Un mari ne peut pas ˆtre m`re et une femme ne peut pas ˆtre p`re. e e e e 7. Deux personnes ayant du sang en commun ne peuvent se marier. 37
  • 39. Chapitre 3 Corrig´s e 3.1 Introduction au PL/SQL −− E x e r c i c e 1 DECLARE a N ME U B R; b N ME U B R; t N ME U B R; BEGIN a := 1 ; b := 2 ; DBMS_OUTPUT . PUT_LINE ( ’a = ’ | | a ) ; DBMS_OUTPUT . PUT_LINE ( ’b = ’ | | b ) ; DBMS_OUTPUT . P U T _ L I N E ( ’ Let ’ ’ s swap a and b . . . The r e s u l t is : ’ ); t := a ; a := b ; b := t ; DBMS_OUTPUT . PUT_LINE ( ’a = ’ | | a ) ; DBMS_OUTPUT . PUT_LINE ( ’b = ’ | | b ) ; END; / −− E x e r c i c e 2 DECLARE a N ME U B R; res N M E U B R; counter N M E U B R; BEGIN a := 1 0 ; r e s := 1 ; c o u n t e r := a ; WHILE counter > 0 LOOP r e s := r e s ∗ c o u n t e r ; c o u n t e r := c o u n t e r − 1 ; END L O O P ; D B M S _ O U T P U T . P U T _ L I N E ( a | | ’ != ’ | | r e s ) ; END; / −− E x e r c i c e 3 DECLARE a N M E := 4 8 ; U BR b N M E := 8 4 ; U BR amodb N M E U B R; BEGIN D B M S _ O U T P U T . P U T ( ’PGCD( ’ | | a | | ’ , ’ | | b | | ’ ) = ’ ) ; WHILE b > 0 LOOP a m o d b := a ; W H I L E a m o d b >= b L O O P a m o d b := a m o d b − b ; END L O O P ; a := b ; b := a m o d b ; END L O O P ; DBMS_OUTPUT . PUT_LINE ( a ) ; END; / 38
  • 40. 3.2 Tableaux et Structures SET S E R V E R O U T P U T ON −− Tableaux DECLARE T Y P E m o n t a b I S V A R R A Y ( 5 0 ) O F INTEGER ; t montab ; BEGIN t := m o n t a b ( ) ; t . extend ( 2 0 ) ; −− I n i t i a l i s a t i o n F O R i IN 1 . . 2 0 L O O P t ( i ) := i ∗ i ; END L O O P ; −− I n v e r s i o n de l ’ o r d r e d e s ´ l´ m e n t s e e DECLARE temp i n t e g e r ; BEGIN F O R i IN 1 . . 1 0 L O O P t e m p := t ( i ) ; t ( i ) := t (20− i + 1 ) ; t (20− i +1) := t e m p ; END L O O P ; END; −− A f f i c h a g e F O R i IN 1 . . 2 0 L O O P DBMS_OUTPUT . PUT_LINE ( ’ t ( ’ | | i || ’) = ’ || t(i )); END L O O P ; −− Tri ` b u l l e a DECLARE temp i n t e g e r ; BEGIN F O R i IN R E V E R S E 2 . . 2 0 L O O P F O R j IN 2 . . i L O O P IF t ( j − 1) > t ( j ) T E H N t e m p := t ( j ) ; t ( j ) := t ( j − 1 ) ; t ( j −1) := t e m p ; END I F ; END L O O P ; END L O O P ; END; −− A f f i c h a g e F O R i IN 1 . . 2 0 L O O P DBMS_OUTPUT . PUT_LINE ( ’ t ( ’ | | i || ’) = ’ || t(i )); END L O O P ; −− Recherche par d i c h o t o m i e de l ’ ´ l´ m e n t 225 e e DECLARE i n f INTEGER := 1 ; s u p INTEGER := 2 0 ; m INTEGER ; X INTEGER := 4 0 0 ; BEGIN LOOP DBMS_OUTPUT . PUT_LINE ( ’ i n f = ’ | | inf || ’ ; sup = ’ | | s u p ) ; m := ( i n f + s u p ) / 2 ; EXIT W E HN t ( m ) = X OR i n f = s u p ; IF t ( m ) > X T E H N s u p := m −1; ELSE i n f := m +1; END I F ; END L O O P ; IF t ( m ) = X T E H N DBMS_OUTPUT . PUT_LINE ( X | | ’ e s t dans l e t a b l e a u ’ ) ; ELSE DBMS_OUTPUT . PUT_LINE ( X | | ’ n” e s t pas dans l e t a b l e a u ’ ) ; END I F ; END; END; / 39
  • 41. −− S t r u c t u r e s DECLARE −− M a i l l o n d ’ une l i s t e c h aˆn´ e ı e TYPE CELL IS RECORD ( −− Donn´e de chaque m a i l l o n e d a t a INTEGER, −− I n d i c e du m a i l l o n p r´ c´ d e n t de l a l i s t e , e e −− −1 s ’ i l n ’ y en a pas p r e v i o u s INTEGER, −− I n d i c e du m a i l l o n s u i v a n t de l a l i s t e , −− −1 s ’ i l n ’ y en a pas next INTEGER ); −− Type t a b l e a u c o n t e n a n t l e s m a i l l o n s de l a l i s t e TYPE TREE IS VARRAY ( 1 9 ) OF CELL ; −− Tableau c o n t e n a n t l e s m a i l l o n s de l a l i s t e t TREE ; −− i n d i c e du premier ´ l´ m e n t de l a l i s t e e e first integer ; −− i n d i c e du d e r n i e r ´ l´ m e n t de l a l i s t e e e last integer ; BEGIN t := T R E E ( ) ; t . extend ( 1 9 ) ; −− I n i t i a l i s a t i o n F O R i IN 1 . . 1 9 L O O P t ( i ) . d a t a := p o w e r ( i , 5 ) m o d 19 ; t ( i ) . p r e v i o u s := i −1; t ( i ) . next := i +1; END L O O P ; f i r s t := 1 ; l a s t := 1 9 ; t ( f i r s t ) . p r e v i o u s := −1; t ( l a s t ) . next := −1; −− A f f i c h a g e DECLARE p i n t e g e r := f i r s t ; BEGIN W H I L E p <> −1 L O O P DBMS_OUTPUT . PUT_LINE ( ’ ( ’ | | p | | ’, ’ || t ( p ) . data | | ’ , ’ | | t ( p ) . previous | | ’ , ’ | | t ( p ) . next | | ’ ) ’ ) ; p := t ( p ) . next ; END L O O P ; END; −− I n v e r s i o n de l ’ o r d r e d e s ´ l´ m e n t s e e DECLARE t e m p INTEGER ; BEGIN F O R i IN 1 . . 1 9 L O O P t e m p := t ( i ) . p r e v i o u s ; t ( i ) . p r e v i o u s := t ( i ) . next ; t ( i ) . next := t e m p ; END L O O P ; f i r s t := 1 9 ; l a s t := 1 ; END; −− A f f i c h a g e DECLARE p i n t e g e r := f i r s t ; BEGIN W H I L E p <> −1 L O O P DBMS_OUTPUT . PUT_LINE ( ’ ( ’ | | p || ’ , ’ || t ( p ) . data | | ’ , ’ | | t ( p ) . previous | | ’ , ’ || t ( p ) . next | | ’ ) ’ ) ; p := t ( p ) . next ; END L O O P ; END; −− Tri ` b u l l e a DECLARE i i n t e g e r := l a s t ; j integer ; BEGIN W H I L E t ( t ( i ) . p r e v i o u s ) . p r e v i o u s <> −1 L O O P j := f i r s t ; W H I L E i< >j L O O P I F ( t ( j ) . d a t a > t ( t ( j ) . next ) . d a t a ) T E H N 40