Introduction au PL/SQL Oracle         Alexandre Mesl´                       e          17 octobre 2011
Table des mati`res              e1 Notes de cours                                                                         ...
2 Exercices                                                                                                               ...
Chapitre 1Notes de cours1.1     Introduction au PL/SQL1.1.1    PL/SQL    Le PL de PL/SQL signifie Procedural Language. Il s...
1.1.5       Traitements conditionnels    Le IF et le CASE fonctionnent de la mˆme fa¸on que dans les autres langages imp´r...
1.2     Tableaux et structures1.2.1    TableauxCr´ation d’un type tableau  e   Les types tableau doivent ˆtre d´finis expli...
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).          ...
p point ;   permet de d´clarer une variable p de type point.              eUtilisation d’une variable de type structur´   ...
1.3     Utilisation du PL/SQL   Ce cours est une introduction aux interactions possibles entre la base de donn´es et les s...
1.3.3     Transactions    Un des m´canismes les plus puissants des SGBD r´cents r´side dans le syst`me des transactions. U...
1.4      Exceptions    Le m´canisme des exceptions est impl´ment´ dans la plupart des langages r´cent, notament orient´s o...
END;    Les deux variables globales SQLCODE et SQLERRM contiennent respectivement le code d’erreur Oracle et un messaged’e...
DECLARE           GLUBARF EXCEPTION;BEGIN        RAISE GLUBARF ;EXCEPTION        W E GLUBARF THEN         HN              ...
1.5     Sous-programmes1.5.1     Proc´dures              eSyntaxe   On d´finit une proc´dure de la sorte       e           ...
RETURN module ( a − b , b ) ;          END IF ;END;Invocation    Tout comme les proc´dures, l’invocation des fonctions ne ...
1.6     Curseurs1.6.1    Introduction    Les instructions de type SELECT ... INTO ... manquent de souplesse, elles ne font...
Fermeture  Apr`s utilisation, il convient de fermer le curseur.     eCLOSE /∗ nomcurseur ∗/ ;  Compl´tons notre exemple,  ...
1.7     Curseurs parametr´s                         e1.7.1    Introduction   A votre avis, le code suivant est-il valide ?...
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...
1.8      Triggers1.8.1     Principe   Un trigger est une proc´dure stock´e qui se lance automatiquement lorsqu’un ´v´nemen...
DELETE F O CLIENT        R M              ∗ERREUR ` la ligne 1 :        aORA −20555: Va te faire . . .ORA −06512: ` ”SCOTT...
SQL>   CREATE OR REPLACE TRIGGER beforeStatement  2    BEFORE UPDATE ON CLIENT  3    DECLARE  4      NB N M E             ...
SQL>SQL>SQL>    CREATE OR REPLACE TRIGGER afterForEachRow  2     AFTER UPDATE ON CLIENT  3     FOR EACH ROW  4     DECLARE...
BEFORE INSERT ON COMPTECLIENTFOR EACH ROWDECLARE         nbComptes N M E                      U B R;BEGIN        SELECT nb...
DELETE F O MIRRORPERSONNE                              R M                      W E E numpers = : old . numpers ;         ...
1.9     Packages1.9.1    Principe    Un package est un ensemble de sous-programmes et de variables form´ par  e    – Une s...
/    On peut utiliser un package depuis n’importe quel script PL/SQL :DECLARE           nb N M E               U B R;BEGIN...
Chapitre 2Exercices2.1     Introduction au PL/SQLExercice 1   Ecrivez un programme affectant les valeurs 1 et 2 ` deux vari...
2.2     Tableaux et StructuresExercice 1  1. Cr´ez un type tableau pouvant contenir jusqu’` 50 entiers.       e           ...
-- AffichageDECLAREp integer := first;BEGINWHILE p <> -1 LOOPDBMS_OUTPUT.PUT_LINE(’(’ || p || ’, ’ ||                     ...
2.3     Utilisation PL/SQL   Nous travaillerons sur les donn´es A.6 et A.5.                                  e   Vous n’ou...
2.4     Exceptions   Nous utiliserons les donn´es de A.7 et A.5                            e   Vous ˆtes invit´s ` modifier...
2.5     Sous-programmesExercice 1   Ecrire une fonction r´cursive retournant bn , avec n entier positif ou nul.           ...
2.6    CurseursExercice 1  Refaites les exercices de 2.3 en utilisant les curseurs.Exercice 2  En utlisant les donnees A.5...
2.7     Curseurs parametr´s                         e   L’int´rˆt de ces exercices ´tant de vous familiariser avec les cur...
2.8     Triggers   Impl´mentez les contraintes suivantes dans les donn´es de les donn´es de A.8. Vous ferez des sous-progr...
2.9          PackagesExercice 1   Lancez deux sessions simultan´ment sur le mˆme serveur et invoquez les sous-programmes d...
2.10    R´visions         e  Impl´mentez les contraintes suivantes dans les donn´es de A.9.      e                        ...
Chapitre 3Corrig´s      e3.1         Introduction au PL/SQL−− E x e r c i c e 1DECLARE            a N ME               U B...
3.2         Tableaux et StructuresSET S E R V E R O U T P U T ON−− TableauxDECLARE            T Y P E m o n t a b I S V A ...
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
Oracle
Prochain SlideShare
Chargement dans…5
×

Oracle

420 vues

Publié le

Publié dans : Business
0 commentaire
0 j’aime
Statistiques
Remarques
  • Soyez le premier à commenter

  • Soyez le premier à aimer ceci

Aucun téléchargement
Vues
Nombre de vues
420
Sur SlideShare
0
Issues des intégrations
0
Intégrations
3
Actions
Partages
0
Téléchargements
25
Commentaires
0
J’aime
0
Intégrations 0
Aucune incorporation

Aucune remarque pour cette diapositive

Oracle

  1. 1. Introduction au PL/SQL Oracle Alexandre Mesl´ e 17 octobre 2011
  2. 2. Table des mati`res e1 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. 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 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 373 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 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63A 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. 4. Chapitre 1Notes de cours1.1 Introduction au PL/SQL1.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 edes traitements complexes sur une base de donn´es. Les possibilit´s offertes sont les mˆmes qu’avec des langages e e eimp´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 etoirement par un /, sinon SQL+ ne l’interpr`te pas. S’il contient des erreurs de compilation, il est possible d’afficher les emessages 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 ede variables, et un ensemble d’instructions dans lequel les variables d´clar´es sont visibles. e e La syntaxe estDECLARE /∗ 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 een argument une valeur ` afficher ou une variable dont la valeur est ` afficher. Par d´faut, les fonctions d’affichage a a esont desactiv´es. Il convient, ` moins que vous ne vouliez rien voir s’afficher, de les activer avec la commande SQL+ e aSET SERVEROUTPUT ON.1.1.4 Variables Une variable se d´clare de la sorte : enom type [ : = initialisation ] ; L’initisation est optionnelle. Nous utiliserons les mˆmes types primitifs que dans les tables. Par exemple : eSET SERVEROUTPUT ONDECLARE 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. 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 eIF /∗ 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 ; voireIF /∗ 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 cCASE /∗ 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 ∗/ eEND CASE;1.1.6 Traitements r´p´titifs e e LOOP ... END LOOP ; permet d’impl´menter les boucles eLOOP /∗ 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 ∗/ ; HNEND 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. 6. 1.2 Tableaux et structures1.2.1 TableauxCr´ation d’un type tableau e Les types tableau doivent ˆtre d´finis explicitement par une d´claration de la forme e e eTYPE /∗ 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 aTYPE 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 eun tableau appel´ t de type numberTab, eDECLARE 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 eer´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 emalloc. Si, par exemple, un type tableau numtab a ´t´ cr´e, la fonction numtab() retourne une tableau vide. ee eDECLARE 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 eequ’il va contenir. On utilise pour cela la m´thode EXTEND(). EXTEND s’invoque en utilisant la notation point´e. Par e eexemple,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. 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). eeIl 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 eassoci´. eUtilisation 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 eLes ´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. eeDECLARE 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, eces variables s’appellent aussi des champs.Cr´ation d’un type structur´ e e On d´finit un type structur´ de la sorte : e eTYPE /∗ 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 eliste 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 estructures, 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 emˆme pour d´clarer des variables en PL/SQL, par exemple e e 6
  8. 8. p point ; permet de d´clarer une variable p de type point. eUtilisation 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 ev.c est le champ appel´ c de la variable structur´ appel´e v. Par exemple, e e eDECLARE 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 eet ordonnee du point p les valeurs 1 et 3. 7
  9. 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. e1.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 eSELECT champ_1 , . . . , champ_n INTO v_1 , . . . , v_nF O ... R M affecte aux variables v 1, ..., v n les valeurs retourn´es par la requˆte. Par exemple e eDECLARE num N M E U B R; nom V R H R 3 0 ) := ’ Poup´ e Batman ’ ; A C A 2( eBEGIN 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 ) ; eEND;/ Prˆtez attention au fait que la requˆte doit retourner une et une une seule ligne, sinon, une erreur se produit ` e e al’ex´cution. e1.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 eallez mettre dedans ! Si vous tenez ` y mettre une valeur qui se trouve dans une colonne d’une table, il est possible de avous r´f´rer directement au type de cette colonne avec le type nomTable.nomColonne%type. Par exemple, eeDECLARE num PRODUIT . numprod%type ; nom PRODUIT . nomprod%type := ’ Poup´ e Batman ’ ; eBEGIN 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 ) ; eEND;/ 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 eporte 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 ) ; eEND;/ 8
  10. 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 eest un ensemble d’op´rations “atomiques”, c’est-`-dire indivisible. Nous consid´rerons qu’un ensemble d’op´rations est e a e eindivisible 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 ePar exemple, dans le cas d’une base de donn´es de gestion de comptes en banque, un virement d’un compte ` un autre e ase 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 esurvient pendant la deuxi`me op´ration, et que la transaction est interrompue, le virement est incomplet et le patron e eva 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 ose casser la tˆte ` tester les erreurs ` chaque ´tape et ` balancer des instructions permettant de “revenir en arri`re”, e a a e a enous 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 eCOMMIT), COMMIT les enregistre d´finitivement dans la base de donn´es. e eLa variable d’environnement AUTOCOMMIT, qui peut ˆtre positionn´e ` ON ou ` OFF permet d’activer la gestion des e e a atransactions. Si elle est positionn´e ` ON, chaque instruction a des r´percussions imm´diates dans la base, sinon, les e a e emodifications ne sont effectives qu’une fois qu’un COMMIT a ´t´ ex´cut´. ee e e 9
  11. 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 efa¸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 a1.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 eexemple GLUBARF. Lorsque dans les instructions, l’erreur GLUBARF se produit, le code du BEGIN s’interrompt et lecode 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 aparticulier pour rattraper (ou propager) l’erreur. Quand un bloc est trait´, les WHEN suivants ne sont pas ´valu´s. e e eOTHERS 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 esuivant :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. 12. END; Les deux variables globales SQLCODE et SQLERRM contiennent respectivement le code d’erreur Oracle et un messaged’erreur correspondant ` la derni`re exception lev´e. Chaque exception a donc, en plus d’un nom, un code et un a e emessage.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( eBEGIN 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 ) ; eEXCEPTION 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 . . . ’ ) ; eEND;/ SELECT numprod INTO num... l`ve une exception si la requˆte renvoie un nombre de lignes diff´rent de 1. e e e1.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´ ede se reporter ` la documentation pour les obtenir. On les traite de la fa¸on suivante a cEXCEPTION 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 el’instruction RAISE. Par exemple, 11
  13. 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. 14. 1.5 Sous-programmes1.5.1 Proc´dures eSyntaxe On d´finit une proc´dure de la sorte e eCREATE 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 arebours.CREATE OR REPLACE PROCEDURE compteARebours ( n N M E U B R) ISBEGIN 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 eCALL. Par exemple, on invoque le compte ` rebours sous SQL+ avec la commande CALL compteARebours(20). aPassage 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 eCREATE OR REPLACE PROCEDURE incr ( val IN OUT N M E U B R) ISBEGIN val := val + 1 ;END;1.5.2 FonctionsSyntaxe On cr´e une nouvelle fonction de la fa¸on suivante : e cCREATE 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, aCREATE OR REPLACE FUNCTION module ( a N M E , b N M E U BR U B R) RETURN N M E IS U BRBEGIN IF a < b THEN RETURN a ; ELSE 13
  15. 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 ec’est quelque peu particulier. On passe par une pseudo-table nomm´e DUAL de la fa¸on suivante : e cSELECT module ( 2 1 , 1 2 ) F O DUAL ; R MPassage de param`tres e Les param`tres sont toujours pass´s avec le type IN. e e 14
  16. 16. 1.6 Curseurs1.6.1 Introduction Les instructions de type SELECT ... INTO ... manquent de souplesse, elles ne fontionnent que sur des requˆtes eretourant une et une seule valeur. Ne serait-il pas int´ressant de pouvoir placer dans des variables le r´sultat d’une e erequˆte retournant plusieurs lignes ? A m´diter... e e1.6.2 Les curseurs Un curseur est un objet contenant le r´sultat d’une requˆte (0, 1 ou plusieurs lignes). e ed´claration e Un curseur se d´clare dans une section DECLARE : eCURSOR /∗ 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 eCURSOR emp_cur IS SELECT ∗ F O EMP ; R MOuverture 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 eretourn´es par la requˆte. On ouvre un curseur dans une section BEGIN : e eOPEN /∗ nomcurseur ∗/ ; Par exemmple,DECLARE CURSOR emp_cur IS SELECT ∗ F O EMP ; R MBEGIN 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 eutilisant le mot-cl´ FETCH : eFETCH /∗ 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 aDECLARE CURSOR emp_cur IS SELECT ∗ F O EMP ; R M ligne emp_cur%rowtypeBEGIN 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. 17. Fermeture Apr`s utilisation, il convient de fermer le curseur. eCLOSE /∗ nomcurseur ∗/ ; Compl´tons notre exemple, eDECLARE 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 eDECLARE 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. 18. 1.7 Curseurs parametr´s e1.7.1 Introduction A votre avis, le code suivant est-il valide ?DECLARE N M E n := 1 4 ; U BRBEGIN 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 ePourquoi ? Parce que les valeurs des ces sont susceptibles de changer entre la d´claration du curseur et son ouverture. eLe rem`de est un curseur param´tr´. e e e1.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 al’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 eenfants : 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. 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 eDECLARE 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. 20. 1.8 Triggers1.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 eon entend dans ce cours toute modification des donn´es se trouvant dans les tables. On s’en sert pour contrˆler ou e oappliquer des contraintes qu’il est impossible de formuler de fa¸on d´clarative. c e1.8.2 ClassificationType 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 edans ce cours des triggers pour les ´v´nements suivants : e e – INSERT – DELETE – UPDATEMoment 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 eEv´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 e1.8.3 Cr´ation eSyntaxe On d´clare un trigger avec l’instruction suivante : eCREATE 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 eeSQL> SELECT C U T( ∗ ) O N 2 F O CLIENT ; R M C U T( ∗ ) O N−−−−−−−−−− 21SQL> DELETE F O CLIENT ; R M 19
  21. 21. DELETE F O CLIENT R M ∗ERREUR ` la ligne 1 : aORA −20555: Va te faire . . .ORA −06512: ` ”SCOTT.PASDEDELETEDANSCLIENT” , ligne 2 aORA −04088: erreur lors d ex´ cution du d´ clencheur ’SCOTT.PASDEDELETEDANSCLIENT ’ e eSQL> 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 eun message d’erreur message. Vous remarquez que comme l’erreur a ´t´ lev´e avant la suppression, les donn´es sont ee e etoujours 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 eune 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 ae e e e ed´clench´ le trigger. e eCREATE OR REPLACE TRIGGER afficheEvenementBEFORE INSERT OR UPDATE OR DELETE ON CLIENTFOR EACH ROWBEGIN 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 lanouvelle ligne par l’interm´diaire des deux variables structur´es :old et :new. Par exemple le trigger suivant empˆche e e ede diminuer un salaire :CREATE OR REPLACE TRIGGER pasDeBaisseDeSalaireBEFORE UPDATE ON EMPFOR EACH ROWBEGIN 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. 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 eeSQL>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 eeSQL>SQL> UPDATE CLIENT SET nomcli = nomcli ;21 ligne ( s ) mise ( s ) ` jour . aSQL>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 eeSQL>SQL> UPDATE CLIENT SET nomcli = nomcli ;UPDATE CLIENT SET nomcli = nomcli ∗ERREUR ` la ligne 1 : aORA −04091: la table SCOTT . CLIENT est en mutation ; le d´ clencheur ou la efonction ne peut la voirORA −06512: ` ”SCOTT.BEFOREFOREACHROW” , ligne 4 aORA −04088: erreur lors d ex´ cution du d´ clencheur ’SCOTT.BEFOREFOREACHROW’ e eSQL> DROP TRIGGER beforeForEachRow ;D´ clencheur supprim´ . e e 21
  23. 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 eeSQL>SQL> UPDATE CLIENT SET nomcli = nomcli ;UPDATE CLIENT SET nomcli = nomcli ∗ERREUR ` la ligne 1 : aORA −04091: la table SCOTT . CLIENT est en mutation ; le d´ clencheur ou la efonction ne peut la voirORA −06512: ` ”SCOTT.AFTERFOREACHROW” , ligne 4 aORA −04088: erreur lors d ex´ cution du d´ clencheur ’SCOTT.AFTERFOREACHROW’ e e1.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 eColonnes 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 edans la table client une colonne contenant le nombre de comptes.ALTER TABLE CLIENT A D nbComptes number ; DUPDATE 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 ebonnes valeurs. On le fait avec plusieurs sous-programmes :CREATE OR REPLACE TRIGGER metAJourNbComptesAFTER INSERT OR UPDATE OR DELETE ON COMPTECLIENTBEGIN 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. 24. BEFORE INSERT ON COMPTECLIENTFOR EACH ROWDECLARE 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 : cCREATE OR REPLACE TRIGGER initialiseNbComptesBEFORE INSERT ON CLIENTFOR EACH ROWBEGIN : new . nbComptes := 0 ;END;/CREATE OR REPLACE TRIGGER metAJourNbComptesAFTER INSERT OR UPDATE OR DELETE ON COMPTECLIENTFOR EACH ROWBEGIN 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 ede graphe. Ce qui n´cessite des SELECT dans la table en cours de mutation. La seule solution est dans ce cas d’avoir eune 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 ecircuits.CREATE TABLE MIRRORPERSONNE(numpers N M E PRIMARY KEY, U BRpere N M E , U BRmere 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 eCREATE OR REPLACE TRIGGER miseAJourMirrorPersonneBEFORE UPDATE OR INSERT OR DELETE ON PERSONNEFOR EACH ROWBEGIN IF DELETING OR UPDATING THEN 23
  25. 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 eCREATE 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 verifieCircuitAFTER UPDATE OR INSERT ON PERSONNEFOR EACH ROWBEGIN 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. 26. 1.9 Packages1.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 esatisfait 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 ecorps d’un package sans changer sa sp´cification, donc sans modifier le fonctionnement de l’application. e1.9.2 Sp´cification e La syntaxe permettant de cr´er l’entˆte est la suivante : e eCREATE 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 : eCREATE 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. 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. 28. Chapitre 2Exercices2.1 Introduction au PL/SQLExercice 1 Ecrivez un programme affectant les valeurs 1 et 2 ` deux variables a et b, puis permutant les valeurs de ces deux avariables.Exercice 2 Ecrivez un programme pla¸ant la valeur 10 dans une variable a, puis affichant la factorielle de a. cExercice 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. 29. 2.2 Tableaux et StructuresExercice 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 aExercice 3 Recherchez, par dichotomie, si l’´l´ment 225 se trouve dans le tableau. eeExercice 4 On impl´mente des listes chaˆ ees avec des tableaux de la sorte, e ın´SET SERVEROUTPUT ONDECLARE-- Maillon d’une liste cha^n´e ı eTYPE CELL IS RECORD(-- Donn´e de chaque maillon edata INTEGER,-- Indice du maillon pr´c´dent de la liste, e e -- -1 s’il n’y en a pasprevious INTEGER,-- Indice du maillon suivant de la liste, -- -1 s’il n’y en a pasnext INTEGER);-- Type tableau contenant les maillons de la listeTYPE TREE IS VARRAY (19) OF CELL;-- Tableau contenant les maillons de la listet TREE;-- indice du premier ´l´ment de la liste e efirst integer;-- indice du dernier ´l´ment de la liste e elast integer;BEGINt := TREE();t.extend(19);-- InitialisationFOR i IN 1..19 LOOPt(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. 30. -- AffichageDECLAREp integer := first;BEGINWHILE p <> -1 LOOPDBMS_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... */ eEND;/ 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 emaillons, vous n’avez le droit de toucher qu’au chaˆınage. Bon courage, l’aspirine n’est pas fournie. 29
  31. 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 aUtilisez une boucle dans laquelle vous placerez une requˆte pour recopier les couples nom/pr´nom de la table personne e edans 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 eExercice 3 Ouvrez un compte courant pour chaque personne, effectuez un d´pˆt en esp`ce ´gal ` numpers ∗ 100 euros. e o e e aExercice 4 Ouvrez un livret pour chaque personne ayant un numpers pair, faites un virement de leur compte courant vers celivret de sorte qu’il ne reste plus que 500 sur leur compte. 30
  32. 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 evous rattraperez les exceptions NO DATA FOUND et TOO MANY ROWS. A chaque insertion, vous ratrapperez l’exceptionDUP 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 eExercice 2 Les scripts remplissant la table Operation ne fonctionneront pas aujourd’hui... Mˆme s’il fonctionnaient la derni`re e efois. 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 esoit. 31
  33. 33. 2.5 Sous-programmesExercice 1 Ecrire une fonction r´cursive retournant bn , avec n entier positif ou nul. eExercice 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. eExercice 3 Ecrire une fonction demi-freres prenant deux num´ros de personnes en param`tre et retournant vrai si et seulement e esi 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 eseulement 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 er´cursivement sur le p`re de cette personne. Faites de sorte ` ne pas utiliser d’exceptions. e e aExercice 6 Ecrire une proc´dure r´cursive affichant les noms des ascendants de sexe masculin de la personne dont le num´ro e e eest pass´ en param`tre. e eExercice 7 Ecrire une fonction r´cursive prenant deux num´ros de personne A et B et retournant vrai si A est un ascendant e ede 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 ede 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 eExercice 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 eg´n´rations. e eExercice 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 cBon courage. 32
  34. 34. 2.6 CurseursExercice 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. 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 econtourner leur usage. Nous utiliserons les donn´es de A.6 eExercice 1 Ecrire une proc´dure qui affiche tous les clients, et pour chaque client, la liste des comptes. eExercice 2 Ecrire une proc´dure qui affiche tous les clients, et pour chaque client, la liste des comptes, et pour chacun de ces ecomptes, l’historique des op´rations. e 34
  36. 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 etenant sur une page, et ne contenant pas plus de trois niveaux d’imbrication. Vous r´pertorierez les num´ros d’erreurs e eque 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. 37. 2.9 PackagesExercice 1 Lancez deux sessions simultan´ment sur le mˆme serveur et invoquez les sous-programmes du package compteur e edepuis chacune des sessions. Que remarquez-vous ?Exercice 2 Impl´menter le corps du package suivant (utilisez les donn´es de A.5). e eCREATE 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. 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. 39. Chapitre 3Corrig´s e3.1 Introduction au PL/SQL−− E x e r c i c e 1DECLARE 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 2DECLARE 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 3DECLARE 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. 40. 3.2 Tableaux et StructuresSET S E R V E R O U T P U T ON−− TableauxDECLARE 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

×