Sommaire
1 Introduction 2 Cration de packages e 2.1 Procdures groupes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . e e 2.2 Cration de packages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . e 3 Cration de sous-programmes de packages e 3.1 Dnition dune procdure . . . . . . . . . . e e 3.2 Dnition de fonction . . . . . . . . . . . . e 3.3 Modes des param`tres de sous-programmes e 3.4 Spcications de sous-programmes . . . . . e 3.5 Param`tres par dfaut de la procdure . . . e e e 3.6 Procdures indpendantes . . . . . . . . . . e e 4 Curseurs 4.1 Dclaration de curseurs . . . . . e 4.2 Le contrle dun curseur . . . . . o 4.3 Attributs des curseurs explicites . 4.4 Param`tres des curseurs . . . . . e 4.5 Cration de packages de curseurs e 3 3 3 3 4 4 5 5 5 6 6 6 6 6 7 7 7 8 8 8 9 9 9 9 10 10 10 10 11
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
5 Variables de procdures e 5.1 Dclaration de variables . . . . . . . e 5.2 Variables locales . . . . . . . . . . . 5.3 Constantes locales . . . . . . . . . . 5.4 Variables globales . . . . . . . . . . . 5.5 Mot-cl DEFAULT . . . . . . . . . . . e 5.6 Attributs des variables et constantes 6 Types de donnes scalaires e 6.1 Boolen . . . . . . . . . . e 6.2 Date/Heure . . . . . . . . 6.3 Caract`re . . . . . . . . . e 6.4 Nombre . . . . . . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
7 Types de donnes composs e e 7.1 Traitement des tableaux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.2 Constructions de tableaux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.3 Traitement des enregistrements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 Structures de contrle o 8.1 Boucles . . . . . . . . . . . . . . . . 8.2 Boucles WHILE . . . . . . . . . . . . . 8.3 Boucles FOR numriques . . . . . . . e 8.4 Boucles FOR de curseurs . . . . . . . 8.5 Structure de contrle conditionnelle o
11 11 12 12 13 13 13 13 14 14 15 15 16 17 17 17 18 18 18 19 19 19 19 22 23 24 25 26 26 26 27 27 28 28 29 29 30 30 31 31 31
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
9 Traitement des exceptions 9.1 Exceptions dnies par lutilisateur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . e 9.2 Exceptions dnies par le syst`me . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . e e 10 Commentaires 11 Procdures catalogues e e 11.1 Rfrencer des procdures catalogues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ee e e 11.2 Etats des procdures catalogues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . e e 11.3 Surcharge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 Commits 13 Package STANDARD 13.1 Rfrences ` des fonctions internes ee a 13.2 Fonctions internes . . . . . . . . . 13.2.1 Fonctions de cha nes . . . . 13.2.2 Fonctions de conversion . . 13.2.3 Fonctions de date . . . . . . 13.2.4 Fonctions diverses . . . . . 13.2.5 Fonctions numriques . . . e
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
14 Complments e 14.1 Instruction DECLARE . . . . . . . . . . . . . 14.2 Conventions de nommage . . . . . . . . . . 14.2.1 Synonymes . . . . . . . . . . . . . . 14.2.2 Porte dune rfrence . . . . . . . . e ee 14.3 Conversion de types de donnes . . . . . . . e 14.4 Triggers (dclencheurs) de bases de donnes e e 14.5 Complments sur les exceptions . . . . . . . e 14.5.1 Relancement dexceptions . . . . . . 14.5.2 Poursuite de lexcution . . . . . . . e 14.5.3 Rexcution de transactions . . . . . e e 14.6 Complments sur les structures de contrle e o 14.6.1 Instruction EXIT . . . . . . . . . . . 14.6.2 Contrle squentiel . . . . . . . . . . o e
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
Ce document est une adaptation dun chapitre de louvrage Oracle Unleashed (SAMS Publishing, 1996).
Introduction
Nous dtaillons ici les structures de PL/SQL, une interface procdurale au syst`me de gestion de base e e e de donnes relationnelle Oracle. Les structures de PL/SQL sont similaires ` celles des langages volus et e a e e fournissent une mthode souple pour manipuler linformation dune base de donnes. e e
2
2.1
Cration de packages e
Procdures groupes e e
PL/SQL permet de grouper tous les programmes dans un objet de la base de donnes appel un package. e e Un ensemble complet de programmes PL/SQL eectuant une certaine tche est appel un package. a e
2.2
Cration de packages e
Avant dtudier les divers aspects du langage PL/SQL, examinons la syntaxe de cration dun package pour e e lcriture dun script facilitant la maintenance en cas de changements. Ce code est la premi`re tape dun e e e package calculant les totaux en dollars dans une commande de marchandises. Cet exemple illustre quelques commandes de cration de packages et de scripts. e set echo on spool order_total CREATE OR REPLACE PACKAGE order_total AS (spcifications du package) e END order_total CREATE OR REPLACE PACKAGE BODY order_total AS (spcifications du corps du package) e END order_total; DROP PUBLIC SYNONYM order_total; CREATE PUBLIC SYNONYM order_total for order_total; GRANT EXECUTE ON order_total TO PUBLIC; spool off SELECT * FROM user_errors WHERE name=ORDER_TOTAL ; La premi`re commande dans ce script, SET ECHO ON, ache un listing du package ` lcran comme e a e il a t compil. La commande ECHO combine avec la commande SPOOL nom cre un chier de listing ee e e e (order_total.lst) ` des ns de debugging. Ce chier contiendra la compilation de la procdure, y compris a e les erreurs, avec les numros de ligne. e CREATE OR REPLACE PACKAGE nom est la commande qui dmarre la construction de la procdure dans la e e base de donnes. Les dclarations dobjets et de sous-programmes dans la zone de spcication du package e e e sont visibles par vos applications. On peut imaginer cette zone comme linterface entre les applications et le code PL/SQL ; au minimum, il faut dnir la procdure dentre ici. En cas de modication ` nimporte quelle e e e a spcication dans cette zone, il faut recrer les applications. La commande END signie la n de la zone de e e spcication du package. e Linstruction CREATE OR REPLACE PACKAGE BODY nom dbute la zone de spcication pour la dclaration e e e dobjets PL/SQL et des sous-programmes que seul le package peut voir. Cette zone nest pas visible pour
lapplication et nest pas ncessaire dans la conception de packages. Toutefois, le fait de concevoir des packages e de cette mani`re vous autorise ` modier les spcications du corps du package sans altrer linterface de e a e e lapplication. Par consquent, les applications nont pas besoin dtre recompiles lorsque ces spcications e e e e internes changent. Une fois encore, linstruction END indique la n des spcications du corps du package. e Dans lexemple, le nom order_total a t choisi ` la fois pour le nom du package et le nom du corps du ee a package, mais les noms auraient pu tre dirents. e e Les trois commandes suivantes sont lies et permettent ` tous les utilisateurs daccder aux procdures de a e e e nies dans le package. Tout dabord, tout synonyme public existant est supprim et puis recr. La commande e ee GRANT fournit un acc`s public au package. e GRANT est une commande qui doit tre excute depuis un compte privilgi. A la n du script se trouve e e e e e ` la commande SPOOL OFF qui clt la sortie dans le chier de listing. Ceci est suivi dune commande SELECT o qui ache toutes les erreurs de compilation dans le terminal o` le script a t lanc. Le nom du champ qui u ee e appara dans cette commande SELECT identie le nom du package cr et doit tre en majuscules. t ee e Le passage du numro de ligne dans le message derreur ` la ligne correspondante dans ou bien le package e a ou bien le corps du package dans le chier de listing va rendre la correction bien plus rapide. Une fois cr, ee le script peut tre excut en utilisant une commande SQL*PLUS de la mani`re suivante : e e e e sqlplus (username/password) @ot Le login spci doit tre un compte privilgi. Apr`s le @ se trouve le nom du script qui contient le texte e e e e e e de cration de package. Dans ce cas, le nom du script est ot.sql, et comme .sql est lextension par dfaut e e des scripts SQL, il nest pas ncessaire de linclure sur la ligne de commande sqlplus. e
La cration de sous-programmes au sein dun package est ltape suivante dans le dveloppement dun e e e package. Il faut dcider quels programmes seront des programmes dinterface avec une application et quels e programmes ne seront disponibles quau sein du package. Ceci dterminera o` la spcication du souse u e programme rsidera dans le package ou dans le corps du package. Il y a deux types de sous-programmes e en PL/SQL, les procdures et les fonctions. e
3.1
Pour dnir une procdure, il faut spcier un nom de routine et les param`tres qui sont reus et rendus e e e e c par la routine. Dans lexemple de order_total, le code qui suit dnit la routine dinterface avec une e application et rside dans la zone de spcication de package : e e PROCEDURE get_order_total ( in_order_num IN NUMBER, out_status_code OUT VARCHAR2, out_msg OUT VARCHAR2, out_merch_total OUT NUMBER, out_shipping IN OUT NUMBER, out_taxes IN OUT NUMBER, out_grand_total OUT NUMBER ); Le mot-cl PROCEDURE dbute la dnition de la routine dinterface get_order_total. Entre parenth`ses e e e e se trouvent les param`tres ` passer entre lapplication et le package order_total. Le point-virgule marque e a la n de la dnition de la procdure. e e La modularit est la cl dune conception dun bon package. Si vous limitez la taille des sous-programmes, e e votre code sera plus facile ` concevoir et corriger. a
3.2
Dnition de fonction e
La dnition dune fonction est tr`s analogue ` la dnition dune procdure, comme le montre lexemple e e a e e ci-dessous : FUNCTION calc_ship_charges ( in_merch_total IN NUMBER ) RETURN NUMBER; Le mot-cl FUNCTION dbute la dnition de la fonction de package calc_ship_charges. Entre parene e e th`ses se trouvent les param`tres ` passer ` la fonction pour calculer les frais de port. Le mot-cl RETURN e e a a e identie le type de donne de la valeur calcule qui va tre retourne. Le point-virgule indique la n de la e e e e dnition de la fonction. e
3.3
Les param`tres peuvent tre dnis IN (mode par dfaut), IN OUT ou OUT, en fonction de la nature de e e e e linformation devant tre passe. Le premier param`tre, in_order_num, est dni avec le mode IN, ce qui e e e e le dsigne comme une valeur passe au sous-programme. Le fait de dnir un param`tre IN lempche de e e e e e recevoir une valeur dans la routine. Les param`tres out_status_code, out_msg, out_merch_total et out_grand_total de lexemple de e dnition de procdure sont dnis comme des valeurs OUT rendues ` lappelant. Ces param`tres sont non e e e a e initialiss ` lentre de la routine et peuvent recevoir une valeur ` lintrieur de la routine. Le fait de dsigner e a e a e e un param`tre OUT interdit de lutiliser dans une expression de sous-programme. e Les param`tres out_shipping et out_taxes sont dnis avec le mode IN OUT. Ces param`tres sont des e e e variables initialises qui sont disponibles pour des raectations dans le sous-programme. e e
3.4
Spcications de sous-programmes e
Apr`s avoir dni un sous-programme et ses param`tres, on dveloppe du code pour le sous-programme. e e e e Lexemple suivant illustre quelques constructions de base quil faut conna tre lorsque lon code un sousprogramme : PROCEDURE init_line_items IS (variables locales) BEGIN (corps du sous-programme) EXCEPTION (traitement des exceptions) END init_line_items; Dans cet exemple, le nom de la procdure est init_line_items avec les variables locales spcies e e e apr`s le mot-cl IS. Le mot BEGIN est le vrai dbut de la procdure (ou fonction) o` le code du souse e e e u programme est dvelopp en mme temps que le traitement des exceptions. La procdure est acheve avec e e e e e END init_line_items. La liste des param`tres de la procdure doit correspondre exactement ` la liste des param`tres de la e e a e spcication pour la procdure qui est dveloppe. Ceci inclut les types de donnes et modes des param`tres e e e e e e inclus dans la spcication. e
3.5
An daccro la exibilit des appels de procdure, des valeurs par dfaut peuvent tre spcies dans tre e e e e e e la dnition de la procdure. De cette mani`re, la procdure peut tre appele avec tous, un ou aucun des e e e e e e param`tres spcis. Des valeurs par dfaut sont donnes aux param`tres qui ne sont pas transmis. Lexemple e e e e e e suivant illustre une dnition de procdure utilisant des param`tres par dfaut : e e e e PROCEDURE calc_ship_charges( merch_total NUMBER DEFAULT 5.95) IS ... Les rfrences ` la procdure calc_ship_charges peuvent ou non inclure une valeur pour merch_total. ee a e Sans cette valeur, la valeur par dfaut est 5.95 comme indiqu. e e
3.6
Procdures indpendantes e e
Les procdures qui ne font pas partie dun package sont appeles indpendantes car elles sont dnies e e e e indpendamment. Ces types de procdures ne sont pas disponibles pour tre rfrences depuis dautres e e e ee e outils Oracle. Une autre limitation des procdures indpendantes est quelles sont compiles ` lexcution, e e e a e ce qui ralentit celle-ci.
Curseurs
PL/SQL utilise des curseurs pour tous les acc`s ` des informations de la base de donnes. Le langage e a e supporte ` la fois lemploi de curseurs implicites et explicites. Les curseurs implicites sont ceux qui sont a tablis lorsquun curseur explicite na pas t dclar. Il faut utiliser des curseurs explicites ou des curseurs e ee e e de boucles FOR dans toutes les requtes qui renvoient plusieurs lignes. e
4.1
Dclaration de curseurs e
Les curseurs sont dnis dans la zone des variables de sous-programmes PL/SQL en utilisant linstruction e CURSOR name IS, comme montr dans lexemple suivant : e CURSOR c_line_item IS (instruction sql) Linstruction SQL peut tre nimporte quelle requte valide. Apr`s linitialisation dun curseur, les actions e e e dun curseur peuvent tre contrles avec les instructions OPEN, FETCH et CLOSE. e oe
4.2
Pour utiliser un curseur an de manipuler des donnes, il faut utiliser linstruction OPEN name pour e excuter la requte et identier toutes les lignes qui satisfont le crit`re de slection. Les extractions ultrieures e e e e e de lignes sont ralises avec linstruction FETCH. Lorsque toutes les donnes sont traites, linstruction CLOSE e e e e clt toute activit associe avec le curseur ouvert. Ce qui suit est un exemple de contrle de curseur : o e e o OPEN c_line_item; ... FETCH c_line_item INTO li_info; ... (traitement de la ligne extraite) ... CLOSE c_line_item;
Ce code ouvre le curseur c_line_item et traite les lignes extraites. Apr`s lextraction et le traitement de e toute linformation, le curseur est ferm. Le traitement des lignes extraites est typiquement contrl par des e oe itrations de boucles comme discut plus loin. e e
4.3
Il y a quatre attributs associs aux curseurs PL/SQL. e %NOTFOUND %FOUND %ROWCOUNT %ISOPEN
Tous les attributs de curseur svaluent ` TRUE, FALSE ou NULL, en fonction de la situation. Lattribut e a %NOTFOUND svalue ` FALSE quand une ligne est extraite, TRUE si le dernier FETCH na pas renvoy une e a e valeur et NULL si le curseur SELECT na pas renvoy de donnes. Lattribut %FOUND est loppos logique de e e e %NOTFOUND par rapport ` TRUE et FALSE, mais svalue nanmoins ` NULL si le curseur ne renvoie pas de a e e a donnes. %ROWCOUNT peut tre utilis pour dterminer combien de ranges ont t slectionnes ` un moment e e e e e ee e e a donn dans le FETCH. Cet attribut est incrment apr`s la slection russie dune ligne. De plus, %ROWCOUNT e e e e e e est ` zro quand le curseur est ouvert pour la premi`re fois. Le dernier attribut, %ISOPEN, est ou bien TRUE a e e ou bien FALSE, suivant que le curseur associ est ouvert ou non. Avant que le curseur ne soit ouvert et apr`s e e quil soit ferm, %ISOPEN vaut FALSE. Dans les autres cas, cet attribut svalue ` TRUE. e e a
4.4
On peut spcier des param`tres pour les curseurs de la mme mani`re que pour des sous-programmes. e e e e Lexemple suivant illustre la syntaxe de dclaration de curseurs avec des param`tres : e e CURSOR c_line_item (order_num IN NUMBER) IS SELECT merch_gross, recipient_num FROM line_item WHERE order_num = g_order_num; Le mode des param`tres est toujours IN, mais les types de donnes peuvent tre nimporte quels types e e e de donnes valides. Un param`tre de curseur ne peut tre rfrenc que pendant la requte dclare. e e e ee e e e e La exibilit au sein des param`tres de curseurs permet au dveloppeur de passer dirents nombres de e e e e param`tres ` un curseur en utilisant le mcanisme des param`tres par dfaut. Ceci est illustr dans lexemple e a e e e e ci-dessous : CURSOR c_line_item (order_num INTEGER DEFAULT 100, line_num INTEGER DEFAULT 1) IS ... En utilisant la dclaration INTEGER DEFAULT, on peut passer tous, un, ou aucun des param`tres de ce e e curseur en fonction du code appelant.
4.5
Un package de curseurs est similaire ` un package de procdures en ce que lon spcie le curseur et a e e son attribut de retour, %TYPE or %ROWTYPE, dans la zone de spcication du package. On spcie ensuite le e e corps du curseur dans la zone de spcication du corps du package. Le fait de regrouper un curseur de cette e mani`re donne la exibilit de changer le corps du curseur sans avoir ` recompiler les applications qui font e e a rfrence ` la procdure groupe. Ce qui suit est un exemple de package de curseur : ee a e e CREATE OR REPLACE PACKAGE order_total AS 7
CURSOR c_line_item RETURN line_item.merch_gross%TYPE; ... END order_total; CREATE OR REPLACE PACKAGE BODY order_total AS CURSOR c_line_item RETURN line_item.merch_gross%TYPE SELECT merch_gross FROM line_item WHERE order_num = g_order_num; ... END order_total; Dans cet exemple, la variable rendue est de mme type que line_item.item_merch_gross. On peut e utiliser lattribut %ROWTYPE pour spcier un enregistrement RETURN qui re`te une ligne dans une table de e e la base de donnes. e
Variables de procdures e
Un aspect important dun langage est la mani`re de dnir les variables. Une fois que les variables sont e e dnies, PL/SQL permet de les utiliser dans des commandes SQL ou dans dautres commandes du langage. La e dnition de constantes au sein de PL/SQL suit les mmes r`gles. De mme, on peut dnir des variables et e e e e e constantes locales ` un sous-programme ou globales ` un package qui est cr. a a ee Il faut dnir les variables et les constantes avant de les rfrencer dans une autre construction. e ee
5.1
Dclaration de variables e
Tout type de donne de PL/SQL ou SQL est un type valide dans une dnition de variable. Les types de e e donnes les plus utiliss sont VARCHAR2, DATE, NUMBER (types de SQL), BOOLEAN et BINARY_INTEGER (types de e e PL/SQL). Les types de donnes scalaires et composs de PL/SQL sont discuts de mani`re plus dtaille plus e e e e e e loin.
5.2
Variables locales
Supposons que lon veuille dclarer deux variables locales nommes merch_gross et recip_count. La e e premi`re, merch_gross, va contenir un nombre ottant ` 10 chires arrondi ` deux dcimales ; recip_count e a a e va contenir un compteur entier. Ces variables sont dclares de la mani`re suivante : e e e merch_gross NUMBER; recip_count BINARY_INTEGER; On peut aussi dclarer merch_gross dans cet exemple avec NUMBER(10,2) pour expliciter le nombre total e de chires et larrondi. Toutefois, si une telle dclaration est lie ` un champ de la base de donnes, elle doit e e a e changer lorsque la dnition de la base de donnes change. e e On peut utiliser deux mthodes pour donner des valeurs aux variables. La premi`re est dutiliser un e e oprateur daectation comme suit : e merch_gross := 10.50; La seconde mthode est dutiliser une commande SQL SELECT ou FETCH qui dnit une valeur de la base e e de donnes comme suit : e SELECT merch_gross INTO merch_gross FROM line_item WHERE order_num = g_order_num; 8
5.3
Constantes locales
La dclaration dune constante est similaire ` la dclaration dune variable sauf que le mot cl CONSTANT e a e e doit suivre le nom de la variable . Il faut immdiatement donner une valeur ` la constante. e a tax_rate CONSTANT NUMBER := 0.03;
5.4
Variables globales
Les variables globales sont dnies de la mme mani`re que des variables locales, mais elles sont dnies e e e e en dehors de toute dnition de procdure. Supposons que lon veuille dnir les variables g_order_num et e e e g_recip_counter pour quelles soient accessibles depuis tous les sous-programmes du package. Cela peut se faire ainsi : CREATE OR REPLACE PACKAGE BODY order_total AS ... g_order_num NUMBER; g_recip_counter BINARY_INTEGER; ... PROCEDURE ... Il faut noter que ces variables globales sont dnies dans la zone de spcication du corps du package e e pour viter quelles ne soient vues par des applications qui appellent la procdure groupe order_total. e e e Si lon utilise des noms de variables identiques ` des noms de colonnes de la base de donnes, les rsultats a e e doprations SELECT ou UPDATE impliquant ces variables sont imprvisibles. e e
5.5
Mot-cl DEFAULT e
Le mot-cl DEFAULT permet dinitialiser des variables sans utiliser loprateur daectation comme dans e e lexemple suivant : merch_gross NUMBER DEFAULT 10.50; On peut aussi utiliser le mot-cl DEFAULT pour initialiser les param`tres dun curseur dans un souse e programme ou des champs dans un enregistrement dni par lutilisateur. e
5.6
Les deux attributs des variables et constantes PL/SQL sont %TYPE et %ROWTYPE. Lattribut %TYPE permet de dclarer des variables similaires ` des colonnes de la base de donnes sans conna le type de la colonne. e a e tre merch_gross peut tre dni de la mani`re suivante : e e e merch_gross line_item.merch_gross%TYPE; La dnition dune variable de cette mani`re permet de rendre eectifs des changements ` la base de e e a donnes lors de la prochaine compilation sans changer le code. e Lattribut %ROWTYPE permet de reprsenter une ligne dune table avec un type de donne enregistrement e e qui masque les colonnes de la base de donnes. Considrons lchantillon de donnes dans la table LINE_ITEM e e e e ci-dessous : Nom de la colonne Donne e order_num 100 line_num 1 merch_gross 10.50 recipient_num 1000
Un curseur peut tre dni au sein dune procdure (voir plus haut) an dextraire des informations de e e e la table LINE_ITEM. En mme temps que le curseur, on dnit une variable ROWTYPE pour stocker les champs e e de cette ligne comme suit : CURSOR c_line_item IS SELECT merch_gross, recipient_num FROM line_item WHERE order_num = g_ordnum; li_info c_line_item%ROWTYPE; Pour extraire les donnes, on utilise FETCH : e FETCH c_line_item INTO li_info; Apr`s le FETCH, on utilise la notation . pour accder ` linformation extraite de la base de donnes. e e a e g_order_merch_total := g_order_merch_total + li_info.merch_gross;
PL/SQL supporte une vaste gamme de types de donnes scalaires pour dnir des variables et des e e ` constantes. A la dirence des types de donnes composites, les types de donnes scalaires nont pas de e e e composantes accessibles. Ces types de donnes tombent dans lune des catgories suivantes : e e Boolen e Date/heure Caract`re e Nombre
6.1
Boolen e
Le type de donnes BOOLEAN, qui ne prend pas de param`tres, est utilis pour stocker une valeur binaire, e e e TRUE ou FALSE. Ce type de donne peut aussi stocker la non-valeur NULL. e
6.2
Date/Heure
Le type de donnes DATE, qui ne prend aucun param`tre, est utilis pour stocker des valeurs de dates. e e e Ces valeurs de date incluent lheure lorsquelles sont stockes dans une colonne de la base de donnes. Les e e dates peuvent stendre du 1er janvier 4712 av. J.-C. au 31 dcembre 4712. Les valeurs par dfaut pour le e e e type de donnes DATE sont les suivantes : e Date : premier jour du mois courant Heure : minuit
6.3
Caract`re e
Le type de donnes caract`re inclut CHAR, VARCHAR2, LONG, RAW et LONG RAW. CHAR est destin aux donnes e e e e de type caract`re de longueur xe et VARCHAR2 stocke des donnes de type caract`re de longueur variable. e e e LONG stocke des cha nes de longueur variable ; RAW et LONG RAW stockent des donnes binaires ou des cha e nes doctets. Les types de donnes CHAR, VARCHAR2 et RAW prennent un param`tre optionnel pour spcier la e e e longueur. type(max_len) 10
Ce param`tre de longueur, max_len, doit tre un entier littral et non une constante ou une variable. e e e La table ci-dessous montre les longueurs maximales et les largeurs des colonnes de la base pour les types de donnes caract`re. e e Type de donnes e Longueur maximale Largeur maximale de colonne CHAR 32767 255 VARCHAR2 32767 2000 LONG 32760 2147483647 RAW 32767 255 LONG RAW 32760 2147483647
Avec cette table, on peut voir la contrainte dintroduction de donnes CHAR, VARCHAR2 et RAW dans des e colonnes de mme type de la base de donnes. La limite est la largeur de la colonne. Toutefois, on peut insrer e e e des donnes de type LONG et LONG RAW de nimporte quelle longueur dans des colonnes similaires parce que e la largeur de colonne est bien plus grande.
6.4
Nombre
Il y a deux types de donnes dans la catgorie des nombres : BINARY_INTEGER et NUMBER. BINARY_INTEGER e e stocke des entiers signs sur ltendue de 231 ` 231 1. Lutilisation la plus courante de ce type de donne e e a e est celle dun index pour des tables PL/SQL. Le stockage de nombres de taille xe ou ottants de nimporte quelle taille est possible avec le type de donne NUMBER. Pour des nombres ottants, la prcision et lchelle e e e peuvent tre spcis avec le format suivant : e e e NUMBER(10,2) Une variable dclare de cette mani`re a un maximum de 10 chires et larrondi se fait ` deux dcimales. e e e a e La prcision par dfaut est le plus grand entier support par le syst`me et 0 est lchelle par dfaut. Lintervalle e e e e e e de prcision va de 1 ` 38 alors que lchelle va de 84 ` 127. e a e a
Les deux types de donnes composites de PL/SQL sont TABLE et RECORD. Le type de donne TABLE permet e e a ` lutilisateur de dnir un tableau PL/SQL. Le type de donnes RECORD permet daller au-del` de lattribut e e a de variable %ROWTYPE ; avec ce type, on peut spcier des champs dnis par lutilisateur et des types de e e donnes pour ces champs. e
7.1
Le type de donnes compos TABLE donne au dveloppeur un mcanisme pour traiter les tableaux. Bien e e e e que ce type soit limit ` une colonne dinformation par tableau PL/SQL, on peut stocker nimporte quel nombre ea de lignes pour cette colonne. Les versions ultrieures dOracle oriront plus de exibilit dans lemploi des e e tableaux. Ce qui suit illustre comment on peut dnir un tableau PL/SQL nomme g_recip_list (linformation e e sera utilise globalement) dans lexemple de order_total. e TYPE RecipientTabTyp IS TABLE OF NUMBER(22) INDEX BY BINARY_INTEGER; ... g_recip_list RecipientTabTyp; Pour initialiser un tableau, il faut tout dabord dnir un nom de tableau ou un type. Dans lexemple e prcdent, cest RecipientTabTyp. Cette colonne de tableau est dnie comme un nombre avec au maximum e e e 22 chires. La colonne peut tre dnie avec nimporte quel type de donnes valide de PL/SQL ; toutefois, la e e e cl primaire, ou INDEX, doit tre de type BINARY_INTEGER. Apr`s avoir dni la structure du tableau, elle e e e e peut tre utilise dans des dnitions de variables, comme cest le cas pour RecipientTabTyp dans lexemple e e e prcdent. e e
11
7.2
Constructions de tableaux
Apr`s leur initialisation, les tableaux sont disponibles pour le stockage dinformation. Pour stocker de e linformation dans le tableau g_recip_list dni dans lexemple prcdent, il sut de rfrencer le tableau e e e ee avec une valeur numrique. Cela est illustr dans lexemple suivant : e e g_recip_list(j) := g_recipient_num(i) ` Dans cet exemple, i et j sont des compteurs avec les valeurs 1..n. A partir du moment o` de linformation u est stocke dans un tableau, on peut y accder, de mani`re numrique, comme indiqu dans lexemple. Dans e e e e e ce cas, les lignes de g_recipient_num sont rfrences pour stockage dans g_recip_list. ee e Le fait de rfrencer une ligne non initialise dans un tableau PL/SQL cause une erreur NO_DATA_FOUND ee e (voir la section sur le traitement des exceptions plus loin).
7.3
Le type de donne composite RECORD procure au dveloppeur un mcanisme pour traiter les enregise e e trements comme dcrit prcdemment. Bien que lon ne puisse pas initialiser un tableau au moment de sa e e e dclaration, il est possible de le faire avec des enregistrements, comme illustr dans lexemple suivant : e e TYPE LineRecTyp IS RECORD (merch_gross NUMBER := 0, recip_num NUMBER := 0 ); ... li_info LineRecTyp; La dnition dun enregistrement de type LineRecTyp permet des dclarations telles que li_info de ce e e type. Cette mthode de dclaration denregistrement peut tre utilise ` la place de la dclaration li_info e e e e a e dans lexemple %ROWTYPE prcdent. Tout comme avec %ROWTYPE, les rfrences aux donnes des enregistree e ee e ments se font avec la notation . . g_order_merch_total := g_order_merch_total + li_info.merch_gross; Il y a trois moyens de donner une valeur ` un enregistrement. Tout dabord, une valeur peut tre donne a e e a ` un champ dun enregistrement tout comme on donne une valeur ` nimporte quelle variable. a li_info.merch_gross := 10.50; Une seconde mthode est de donner une valeur ` tous les champs ` la fois en utilisant deux enregistrements e a a qui sont dclars de mme type. Supposons que new_li_info est une seconde variable de type LineRecTyp : e e e new_li_info := li_info; Cette instruction donne ` tous les champs de new_li_info les valeurs des mmes champs de li_info. a e Il nest pas possible daecter des valeurs denregistrements de dirents types entre eux. e Une troisi`me mani`re de donner des valeurs aux champs dun enregistrement consiste ` utiliser les e e a instructions SQL SELECT ou FETCH. OPEN c_line_item; ... FETCH c_line_item INTO li_info; Dans ce cas, tous les champs de li_info reoivent des valeurs provenant des informations extraites par c la commande FETCH sur le curseur c_line_item.
12
Structures de contrle o
Tout langage procdural a des structures de contrle qui permettent de traiter linformation dune mani`re e o e logique en contrlant le ot des informations. Les structures disponibles au sein de PL/SQL incluent IF-THENo ELSE, LOOP et EXIT-WHEN. Ces structures procurent de la exibilit dans la manipulation des donnes de la e e base de donnes. e
8.1
Boucles
Lutilisation de la commande LOOP fournit un traitement itratif bas sur des choix logiques. La construce e tion de base des boucles LOOP est montre dans lexemple suivant : e <<nom>> LOOP (traitement rptitif) e e END LOOP nom; Pour sortir dune boucle de ce genre, il faut une commande EXIT ou GOTO base sur une condition du e traitement. En cas de leve dexception dnie par lutilisateur, la boucle LOOP sach`ve aussi. Examinons e e e maintenant trois types de boucles PL/SQL qui dnissent des conditions explicites de terminaison. e Une boucle peut tre nomme comme cela a t montr dans lexemple en utilisant une tiquette telle e e ee e e que <<nom>> juste avant linstruction LOOP. Bien que ce ne soit pas obligatoire, ltiquetage permet de garder e une meilleure trace de limbrication des boucles.
8.2
Boucles WHILE
La boucle WHILE vrie ltat dune expression PL/SQL qui doit svaluer ` TRUE, FALSE ou NULL au dbut e e e a e de chaque cycle de traitement. Ce qui suit est un exemple dutilisation de boucles WHILE : WHILE (expression) LOOP (traitement de boucle) END LOOP; Comme indiqu, le programme value lexpression au dbut de chaque cycle de boucle. Le programme e e e excute le traitement de la boucle si lexpression svalue ` TRUE. Une valeur FALSE ou NULL termine la e e a boucle. Les itrations ` travers la boucle sont exclusivement dtermines par lvaluation de lexpression. e a e e e
8.3
Les itrations de boucles peuvent tre contrles avec des boucles FOR numriques. Ce mcanisme permet e e oe e e au dveloppeur dtablir un intervalle dentiers pour lesquels la boucle va tre itre. Lexemple suivant du e e e ee package order_total illustre les boucles numriques FOR : e <<recip_list>> FOR i in 1..g_line_counter LOOP (traitement de boucle) END LOOP recip_list; Dans cet exemple, la boucle est itre pour les entiers de 1 jusqu` la valeur de g_line_counter. La ee a valeur de lindex de boucle i est vrie au dbut de la boucle et incrmente ` la n de la boucle. Lorsque e e e e e a i est gal ` g line counter + 1, la boucle termine. e a
13
8.4
Les boucles FOR de curseurs combinent le contrle de curseurs et des structures de contrle supplmentaires o o e pour la manipulation dinformations de bases de donnes. Lindex de boucle, louverture de curseur, le FETCH e et la fermeture de curseur sont tous implicites lorsque lon utilise des boucles FOR de curseurs. Considrons e lexemple suivant : CURSOR c_line_item IS (instruction sql) BEGIN FOR li_info IN c_line_item LOOP (traitement de lenregistrement extrait) END LOOP; END; Comme montr, le programme dclare explicitement le curseur c_line_item avant quil ne soit rfe e ee renc dans la boucle FOR. Lorsque le programme pn`tre dans la boucle FOR, le code ouvre implicitement e e e c_line_item et cre implicitement lenregistrement li_info comme si la dclaration suivante tait prsente : e e e e li_info c_line_item%ROWTYPE; D`s lentre dans la boucle, le programme peut rfrencer les champs de lenregistrement li_info qui e e ee reoivent des valeurs par le FETCH implicite ` lintrieur de la boucle FOR. Les champs de li_info re`tent c a e e la ligne extraite par le curseur c_line_item. Lorsquil ny a plus de donnes pour FETCH, le curseur c_line_item est implicitement ferm. e e Il nest pas possible de rfrencer linformation contenue dans li_info en dehors de la boucle de curseur. ee
8.5
La structure IF-THEN-ELSE permet davoir des traitements qui dpendent de certaines conditions. Par e exemple, considrons des commandes de marchandises avec des lments sur plusieurs lignes o` une liste e ee u de destinataires est construite. En utilisant des structures de contrle conditionnelles et itratives pour o e construire la liste des destinataires, le code est le suivant : PROCEDURE init_recip_list IS recipient_num NUMBER; i BINARY_INTEGER; j BINARY_INTEGER := 1; k BINARY_INTEGER; BEGIN g_out_msg := init_recip_list; <<recip_list>> FOR i in 1..g_line_counter LOOP IF i = 1 THEN g_recip_list(j) := g_recipient_num(i); j := j + 1; g_recip_list(j) := 0; ELSE FOR k in 1..j LOOP IF g_recipient_num(i) = g_recip_list(k) THEN exit; ELSIF k = j THEN g_recip_list(j) := g_recipient_num(i); j := j + 1; 14
g_recip_list(j) := 0; end IF; end LOOP; end IF; end LOOP recip_list; END; Dans lexemple order_total, le sous-programme init_recip_list construit une liste de numros de e destinataires uniques pour le calcul des frais de port supplmentaires. Il y a une boucle de contrle FOR qui e o parcourt chaque numro de destinataire trouv sur une commande particuli`re. Le tableau g_recip_list est e e e initialis avec le premier numro de destinataire et les numros suivants sont compars avec tous les numros e e e e e uniques dans g_recip_list jusqu` ce quune liste de tous les destinataires ait t rassemble. a ee e Cet exemple illustre aussi lextension ELSIF de IF-THEN-ELSE. Cette partie fournit une structure de contrle supplmentaire avec des test de contraintes additionnelles. Lemploi de ELSIF requiert aussi un o e THEN. Un autre exemple est lemploi de EXIT-WHEN qui permet la compltion dune boucle lorsque certaines e conditions sont satisfaites. Considrons lexemple de sortie de boucle FETCH suivant : e open c_line_item; loop fetch c_line_item into li_info; EXIT WHEN (c_line_item%NOTFOUND) or (c_line_item%NOTFOUND is NULL); Dans cet exemple, la boucle est termine lorsquon ne trouve plus de donnes pour satisfaire le SELECT e e du curseur c_line_item. Lemploi de %NOTFOUND ou %FOUND peut causer des boucles innies si lon ne vrie pas que ces attributs e sont valus ` NULL dans un test logique EXIT-WHEN. e e a
Le traitement des exceptions PL/SQL est un mcanisme pour manipuler les erreurs rencontres lors de e e lexcution. Lutilisation de ce mcanisme permet ` lexcution de continuer si lerreur nest pas susamment e e a e importante pour produire la terminaison de la procdure. La dcision de permettre ` une procdure de e e a e continuer apr`s une condition derreur est une dcision que le dvelopppeur doit faire en fonction des erreurs e e e possibles. Il faut dnir le handler dexception au sein de la spcication dun sous-programme. Les erreurs e e conduisent le programme ` lever une exception et transf`rent le contrle au handler dexceptions. Apr`s a e o e lexcution du handler, le contrle retourne au bloc dans lequel le handler a t dni. Sil ny a plus dinse o ee e tructions excutables dans le bloc, le contrle retourne au code appelant. e o
9.1
PL/SQL permet ` lutilisateur de dnir des handler dexceptions dans la zone des dclarations ou des a e e spcications de sous-programmes. Cela se fait en donnant un nom ` lexception comme dans lexemple e a suivant : ot_failure EXCEPTION; Dans ce cas, le nom de lexception est ot_failure. Le code associ au handler est crit dans la zone de e e spcication EXCEPTION comme indiqu ci-dessous : e e EXCEPTION when OT_FAILURE then out_status_code := g_out_status_code; out_msg := g_out_msg; 15
Cette exception est dnie dans lexemple order_total pour capturer ltat et les donnes associes e e e e pour les exceptions NO_DATA_FOUND rencontres dans un sous-programme. Ce qui suit est un exemple dune e exception de sous-programme : EXCEPTION when NO_DATA_FOUND then g_out_status_code := FAIL; RAISE ot_failure; Au sein de cette exception se trouve la commande RAISE qui transf`re le contrle au handler dexception e o ot_failure. Cette technique pour provoquer des exceptions est utilise pour invoquer toutes les exceptions e dnies par lutilisateur. e
9.2
Des exceptions internes ` PL/SQL sont leves automatiquement en cas derreur. Dans le prcdent exemple, a e e e NO_DATA_FOUND est une exception dnie par le syst`me. La table suivante est une liste compl`te des excepe e e tions internes. Nom de lexception CURSOR_ALREADY_OPEN DUP_VAL_ON_INDEX INVALID_CURSOR INVALID_NUMBER LOGIN_DENIED NO_DATA_FOUND NOT_LOGGED_ON PROGRAM_ERROR STORAGE_ERROR TIMEOUT_ON_RESOURCE TOO_MANY_ROWS TRANSACTION_BACKED_OUT VALUE_ERROR ZERO_DIVIDE Erreur Oracle ORA-06511 ORA-00001 ORA-01001 ORA-01722 ORA-01017 ORA-01403 ORA-01012 ORA-06501 ORA-06500 ORA-00051 ORA-01422 ORA-00061 ORA-06502 ORA-01476
Outre cette liste dexceptions, il y a une exception attrape-tout nomme OTHERS qui permet dattraper e toutes les erreurs pour lesquelles il ny a pas de traitement derreur spcique. Cette exception est illustre e e sur lexemple suivant : when OTHERS then out_status_code := FAIL; out_msg := g_out_msg || || SUBSTR(SQLERRM, 1, 60); Cette technique est utilise dans lexemple de la procdure order_total pour piger toutes les erreurs de e e e procdure autres que NO_DATA_FOUND. Linformation renvoye au code appelant dans out_msg est le nom du e e sous-programme contenu dans g_out_msg concatn avec les 60 premiers caract`res retourns par la fonction e e e e SUBSTR applique ` la fonction SQLERRM. e a ` A la fois SQLERRM et SUBSTR sont des fonctions internes PL/SQL. Une liste compl`te des fonctions internes e est donne plus loin. e SQLERRM ne renvoie un message valide que lorsque cette fonction est appele au sein dun handler dexe ception ` moins quun argument ne soit pass ` la fonction et que cet argument soit un numro derreur a e a e valide de SQL. Le code derreur Oracle est la premi`re partie du message retourn par SQLERRM. Ensuite vient e e le texte associ avec ce code derreur. e De cette mani`re, toutes les erreurs rencontres pendant lexcution dune procdure sont attrapes et e e e e e repasses ` lapplication ` des ns de correction. Ce qui suit est un exemple derreur renvoye par la procdure e a a e e order_total : FAIL: init_line_items ORA-01001: invalid cursor 16
Ce message derreur (format par lapplication) rv`le une opration illgale sur un curseur dans le souse e e e e programme init_line_items. La portion du message retourne par SQLERRM commence avec le code derreur e SQL ORA-01001. Un autre message derreur est illustr dans lexemple suivant : e FAIL: calc_ship_charges Dans ce cas, le sous-programme calc_ship_charges avait une erreur NO_DATA_FOUND. Ceci est dtermin e e par le fait quaucun message derreur SQL nest concatn avec le texte du message. e e
10
Commentaires
Bien que certaines personnes pensent que commenter un programme nest pas ncessaire, il y a deux e moyens de mettre des commentaires au sein de procdures PL/SQL. La premi`re est destine ` des commene e e a taires sur une seule ligne et la syntaxe est indique sur lexemple suivant : e --*************** CREATION DU PACKAGE ORDER_TOTALING *************** Un double tiret au dbut de la ligne indique que cette ligne est un commentaire. Le second moyen est e utilis pour placer une suite de commentaires dans un package PL/SQL. e /* Le code qui suit gn`re une liste de numros de destinataires e e e uniques pour tous les numros de destinataires pour un certain ordre */ e Un bloc de commentaires tel que celui-l` commence avec /* et sach`ve avec */. Les commentaires quels a e quils soient peuvent tre placs ` nimporte quel endroit du code PL/SQL. e e a Les blocs PL/SQL qui sont compils dynamiquement dans les applications Oracle Precompiler ne peuvent e pas utiliser les commentaires mono-lignes.
11
Procdures catalogues e e
Il est possible de stocker du code PL/SQL dans la base Oracle avec les extensions procdurales. Les e avantages des procdures catalogues incluent une maintenance plus aise, des applications plus petites, une e e e excution plus rapide et de plus grandes conomies de mmoire, pour nen citer que quelques uns. e e e
11.1
Un autre avantage important li ` lutilisation de procdures catalogues est la possibilit de rfrencer ea e e e ee la procdure depuis de nombreuses applications Oracle direntes. Il est possible de faire rfrence ` des e e ee a procdures catalogues depuis dautres procdures catalogues, depuis des triggers de bases de donnes, e e e e e depuis des applications construites avec des prcompilateurs Oracle ou des outils Oracle tels que SQL*Forms. e Lexemple suivant appelle le package order_total depuis une autre procdure : e order_total.get_order_total (order_num, status_code, message, merch_gross, shipping, taxes, grand_total); Lexemple suivant montre la mme procdure order_total rfrence depuis PRO*C, une application du e e ee e prcompilateur Oracle. e EXEC SQL BEGIN 17
order_total.get_order_total ( :order_num, :status_code, :message, :merch_gross, :shipping, :taxes, :grand_total); END; END-EXEC; Tous les param`tres dans cet exemple de la procdure order_total sont des variables lies dOracle quil e e e faut dclarer avant de les rfrencer dans le package. Lexemple nal illustre un appel au package order_total e ee depuis une application SQL*Forms. BEGIN ... order_total.get_order_total ( order_num, status_code, message, merch_gross, shipping, taxes, grand_total); ... END; Une fois de plus, il faut dclarer toutes les variables passes en param`tre avant dappeler la procdure. e e e e
11.2
Apr`s compilation, une procdure catalogue existe ou bien sous une forme valide ou bien sous une forme e e e non valide. Sil ny a pas eu de changements ` la procdure, elle est considre valide et peut tre rfrence. a e ee e ee e Si un sous-programme ou un objet rfrenc au sein de la procdure change, son tat devient non valide. ee e e e Seules des procdures dans un tat valide sont disponibles pour rfrence. e e ee Le fait de rfrencer une procdure qui nest pas valide entraine la recompilation par Oracle des objets ee e appels par la procdure rfrence. Si la recompilation choue, Oracle renvoie une erreur dexcution ` e e ee e e e a lappelant et la procdure reste dans un tat non valide. Sinon, Oracle recompile la procdure rfrence et, e e e ee e si la recompilation russit, lexcution se poursuit. e e
11.3
Surcharge
Le concept de surcharge dans PL/SQL est li ` lide que lon peut dnir des procdures et des fonctions ea e e e avec le mme nom. PL/SQL ne consid`re pas seulement le nom rfrenc pour dterminer les procdures et e e ee e e e fonctions appeles, mais aussi le nombre et le type des param`tres formels. e e PL/SQL essaie aussi de rsoudre les appels de procdures ou de fonctions dans des packages dnis locae e e lement avant de regarder dans des fonctions internes ou dans des packages dnis globalement. Pour assurer e encore davantage lappel de la bonne procdure, le point (.) peut tre utilis comme cela a t illustr dans e e e ee e des exemples antrieurs avec des rfrences ` des procdures catalogues. Le fait de prxer un nom de proe ee a e e e cdure ou de fonction par le nom du package dtermine de mani`re unique toute rfrence ` une procdure e e e ee a e ou une fonction.
12
Commits
La commande COMMIT est utilisable dans les procdures PL/SQL ` moins que la procdure soit appele e a e e depuis une application SQL*Forms. Pour autoriser les commits au sein dune procdure appele par une e e 18
application SQL*Forms, il faut excuter la commande ALTER SESSION ENABLE COMMIT IN PROCEDURE avant e dinvoquer lobjet PL/SQL. Comme cette commande ne peut pas tre appele depuis SQL*Forms, il faut crer e e e une sortie utilisateur depuis laquelle la commande ALTER SESSION peut tre excute et ensuite appeler la e e e procdure. Ce qui suit est un exemple dappel de la procdure order_total depuis SQL*Forms au travers e e dune sortie utilisateur : user_exit(order_totl); Dans ce cas, la routine order_totl de la sortie utilisateur SQL*Forms fait rfrence ` la procdure groupe ee a e e order_total.
13
Package STANDARD
PL/SQL fournit divers outils dans un package appel STANDARD pour lutilisation par les dveloppeurs. Ces e e outils incluent des fonctions internes et des exceptions internes.
13.1
Les fonctions PL/SQL internes sont un bon exemple de surcharge par rapport aux noms des procdures e et fonctions. Il faut se rappeler que PL/SQL dtermine quelle procdure ou fonction est appele en cherchant e e e une correspondance ` la fois avec le nombre et le type des param`tres formels et pas seulement avec le nom a e de la procdure ou fonction rfrence. Considrons les deux fonctions internes appeles TO_NUMBER dans e ee e e e lexemple suivant : function TO_NUMBER (str CHAR [, fmt VARCHAR2, [, nlsparms] ]) return NUMBER function TO_NUMBER (str VARCHAR2 [, fmt VARCHAR2 [, nlsparms] ]) return NUMBER Les deux fonctions sont nommes TO_NUMBER, mais le type de donnes du premier param`tre est CHAR e e e dans la premi`re dnition et VARCHAR2 dans la seconde. Les param`tres optionnels sont les mmes dans e e e e les deux cas. PL/SQL rsout lambigu e dun appel ` la fonction TO_NUMBER en regardant le type de donne e t a e du premier param`tre. On pourrait aussi avoir une procdure ou fonction dnie par lutilisateur et appele e e e e TO_NUMBER. Dans ce cas, la dnition locale prend le pas sur la dnition interne de la fonction. Il reste e e possible daccder ` la fonction interne en utilisant la notation . comme suit : e a STANDARD.TO_NUMBER ...
13.2
Fonctions internes
La fonction TO_NUMBER est un exemple de fonction PL/SQL interne. La table ci-dessous donne une liste compl`te des catgories de fonctions PL/SQL avec les valeurs de retour par dfaut. e e e Catgorie e Valeur de retour usuelle 13.2.1 Fonctions de cha nes Caract`re e VARCHAR2 Conversion Aucune Date DATE Divers Aucune Nombre NUMBER
Bien que la plupart des fonctions de cha nes renvoient une valeur de type VARCHAR2, quelques fonctions renvoient dautres valeurs. La table ci-dessous donne la liste des fonctions de cha nes disponibles avec une br`ve description, la liste des arguments et la valeur de retour si elle est dirente de la valeur de retour e e la plus probable pour cette catgorie de fonctions. Les arguments optionnels sont indiqus entre crochets. e e Toutes les fonctions de cha nes internes prennent la forme suivante : function ASCII (char VARCHAR2) return VARCHAR2
19
INSTR
INSTRB
LENGTH
LENGTHB
LOWER
Description Retourne le code standard dun caract`re. e Retourne le caract`re e correspondant ` un code. a Retourne str2 postx ` ea str1. Retourne str1 avec la premi`re lettre de chaque e mot en majuscule et toutes les autres en minuscules. Retourne la position de dpart de str2 dans e str1. La recherche commence en pos pour la ni`me occurence. Si elle e est ngative, la recherche e est eectue depuis la n. e ` A la fois pos et n ont comme valeur par dfaut e 1. La fonction retourne 0 si str2 nest pas trouv. e Similaire ` INSTR sauf a que pos est une position exprime en nombre e doctets. Retourne le nombre de caract`res dans str et e pour le type de donnes e CHAR ; la longueur inclut les blancs de ns. Similaire ` LENGTH ; a retourne un nombre doctets pour str, incluant les blancs de ns pour CHAR. Retourne str avec toutes les lettres en minuscules. str est complt ` eea gauche ` la longueur len a avec les caract`res de e pad, qui est par dfaut un e unique blanc. Retourne les len premiers caract`res dans str si e str est plus long que len.
Argument(s) char VARCHAR2 num NUMBER str1 VARCHAR2, str2 VARCHAR2 str1 VARCHAR2
str1 VARCHAR2, str2 VARCHAR2 [, pos NUMBER [, n NUMBER]] str CHAR ou str VARCHAR2
NUMBER
NUMBER
LPAD
str CHAR ou str VARCHAR2 str VARCHAR2 len NUMBER [, pad VARCHAR2]
CHAR ou VARCHAR2
20
LTRIM
NLS_INITCAP
NLS_LOWER
NLS_UPPER
NLSSORT
Retourne str avec des caract`res retirs jusquau e e premier caract`re qui ne e se trouve pas dans set ; set contient par dfaut e un blanc. Similaire ` INITCAP sauf a que la squence de tri est e spcie par nlsparms. e e Similaire ` LOWER sauf a que la squence de tri est e spcie par nlsparms. e e Similaire ` UPPER sauf a que la squence de tri est e spcie par nlsparms. e e Retourne str avec un tri spci par nlsparms. e e Renvoie str1 o` toutes u les occurences de str2 sont remplaces par str3. e Si str3 nest pas spci, e e toutes les occurences de str2 sont retires. e Similaire ` LPAD sauf que a str est complt ` droite eea avec pad pour atteindre une longueur de len. Similaire ` LTRIM sauf a que les caract`res de n e sont retirs de str apr`s e e le premier caract`re ne se e trouvant pas dans set. Retourne le code phontique soundex de e str. Retourne une sous-cha ne de str commenant ` la c a position pos et de longueur len ou allant jusqu` la n de str si a len est omis. Si pos < 0, SUBSTR compte en arri`re e a ` partir de la n de str. Similaire ` SUBSTR sauf a que lon travaille en octets et non en caract`res. e Remplace toutes les occurences de set1 avec des caract`res de set2 e dans str.
REPLACE
str VARCHAR2 [, nlsparms VARCHAR2] str VARCHAR2 [, nlsparms VARCHAR2] str VARCHAR2 [, nlsparms VARCHAR2] str VARCHAR2 [, nlsparms VARCHAR2] str1 VARCHAR2, str2 VARCHAR2, [str3 VARCHAR2]
RAW
RPAD
str VARCHAR2, len VARCHAR2, [, pad VARCHAR2] str VARCHAR2 [, set VARCHAR2]
NUMBER
RTRIM
SOUNDEX
str VARCHAR2
SUBSTR
SUBSTRB
str VARCHAR2, pos NUMBER [, len NUMBER] str VARCHAR2, set1 VARCHAR2, set2 CHAR
TRANSLATE
21
UPPER
13.2.2
Fonctions de conversion
La table qui suit donne la liste des fonctions de conversion disponibles avec une br`ve description, la e liste des arguments et la valeur de retour. Les arguments optionnels sont indiqus entre crochets. Toutes les e fonctions de conversion internes sont de la forme suivante : function CHARTOROWID (str VARCHAR2) return ROWID Fonction CHARTOROWID Description Convertit str dans le type ROWID. Convertit str de lensemble de caract`res e set1 vers lensemble de caract`res set2. set1 et e set2 peuvent tre des e noms densembles de caract`res ou des noms de e colonnes. Convertit str de CHAR ou VARCHAR2 en RAW. Oppos de HEXTORAW. e Convertit bin de ROWID en cha hexadcimale ne e de 18 octets. Convertit dte en VARCHAR2 en utilisant fmt. La langue pour la conversion de date peut tre spcie en e e e nlsparms. Convertit num en VARCHAR2 en utilisant fmt. Les lments de ee format suivant peuvent tre spcis dans e e e nlsparms : caract`re e dcimal, sparateur de e e groupe et un symbole pour la monnaie locale ou internationale. Convertit le type MLSLABEL en VARCHAR2 en utilisant fmt. Argument(s) str CHAR ou str VARCHAR2 str VARCHAR2, set1 VARCHAR2, set2 VARCHAR2 Valeur de retour ROWID
CONVERT
VARCHAR2
HEXTORAW
RAWTOHEX ROWIDTOCHAR
RAW
VARCHAR2 VARCHAR2
TO_CHAR (Dates)
VARCHAR2
TO_CHAR (Numbers)
VARCHAR2
TO_CHAR (Labels)
VARCHAR2
22
TO_DATE
TO_LABEL
TO_MULTI_BYTE
TO_NUMBER
TO_SINGLE_BYTE
Convertit str ou num en une valeur DATE en utilisant fmt. Largument fmt nest pas optionnel en convertissant un nombre. La langue pour la conversion de date peut tre spcie en e e e nlsparms. Convertit str dans le type de donne MLSLABEL. e Si fmt est omis, str doit tre le format de e ltiquette par dfaut. e e Convertit str dun codage 8 bits en un codage multi-octets, sil existe. Convertit str en une valeur numrique en e fonction de la valeur de fmt. Les lments du ee format peuvent tre e spcis dans nlsparms e e comme dcrit dans la e fonction TO_CHAR. Oppos de e TO_MULTI_BYTE.
DATE
str CHAR ou str VARCHAR2 [, fmt VARCHAR2] str CHAR str VARCHAR2
MLSLABEL
CHAR VARCHAR2
NUMBER NUMBER
CHAR VARCHAR2
13.2.3
Fonctions de date
Toutes les fonctions de date renvoient une valeur de type DATE sauf en cas de spcication contraire dans e la table ci-dessous, qui donne la liste des fonctions de date disponibles avec une br`ve description, la liste e des arguments et la valeur de retour. Les arguments optionnels sont mis entre crochets. Toutes les fonctions de date internes sont de la forme suivante : function ADD_MONTHS (dte DATE, num NUMBER) return DATE Fonction ADD_MONTHS LAST_DAY MONTHS_BETWEEN Description Retourne dte plus ou moins num mois. Retourne le dernier jour du mois de dte. Retourne le nombre de mois entre dte1 et dte2. NUMBER est < 0 si dte1 est antrieur ` dt2. e a Retourne la date et lheure dans la zone zon2 en fonction de la date et heure dte exprime dans e la zone zon1. Argument(s) dte DATE, num NUMBER dte DATE dte1 DATE, dte2 DATE Valeur de retour
NUMBER
NEW_TIME
23
NEXT_DAY
ROUND
SYSDATE
TRUNC
Retourne le premier jour de la semaine pour le jour day qui suit la date dte. Retourne dte arrondi ` a lunit spcie dans le e e e format fmt. Si aucun format nest spci, dte e e est arrondi au jour le plus proche. Retourne la date et lheure courante du syst`me. e Retourne dte o` lheure u du jour est tronque e comme spci dans fmt. e e
Pas darguments.
13.2.4
Fonctions diverses
La table ci-dessous donne la liste des fonctions diverses avec une br`ve description, une liste darguments e et une valeur de retour. Les arguments optionnels sont donns entre crochets. e Fonction DUMP Description Retourne une reprsentation interne de e expr base sur lune des e spcications fmt e suivantes : 8 = octal, 10 = dcimal, e 16 = hexadcimal, e 17 = caract`re simple. e Les arguments pos et len spcient la portion de la e reprsentation ` renvoyer. e a Renvoie la plus grande valeur de exprn. Toutes les expressions doivent tre de type compatible e avec expr1. Retourne la plus grande borne infrieure de la liste e dtiquettes. Chaque e tiquette doit tre de e e type MLSLABEL. Retourne la plus petite valeur de la liste de exprn. Toutes les expressions doivent tre e de type compatible avec expr1. Argument(s) expr DATE ou expr NUMBER ou expr VARCHAR2 [, fmt BINARY_INTEGER [, pos BINARY_INTEGER [, len BINARY_INTEGER]]] expr1, expr2, expr3, ... Valeur de retour VARCHAR2
GREATEST
GREATEST_LB
label [, label] . . .
MLSLABEL
LEAST
24
LEAST_UB
NVL
UID
USER
USERENV
VSIZE
Retourne la plus petite borne suprieure de la e liste des tiquettes. e Chaque tiquette doit e tre de type MLSLABEL. e Retourne la valeur de arg1 si cette valeur nest pas nulle et arg2 dans le cas contraire. arg1 et arg2 doivent tre de e mme type. e Renvoie un unique numro didentication e pour lutilisateur actuel dOracle. Retourne le nom de lutilisateur courant dOracle. Retourne des informations sur la session actuelle bases sur e str, qui peut avoir lune des valeurs suivantes : ENTRYID (identicateur dentre), LABEL e (tiquette de la session), e LANGUAGE (langue, territoire et ensemble des caract`res de la base), e SESSIONID (identicateur de session), TERMINAL (type de terminal de la session) Retourne le nombre doctets dans expr.
label [, label] . . .
MLSLABEL
arg1, arg2
Pas darguments
NUMBER
Pas darguments
VARCHAR2
str VARCHAR2
VARCHAR2
NUMBER
13.2.5
Fonctions numriques e
Toutes les fonctions numriques renvoient une valeur de type NUMBER sauf indication contraire dans la e table ci-dessous, qui donne la liste des fonctions numriques disponibles avec une br`ve description, la liste des e e arguments et la valeur de retour. Les arguments optionnels sont donns entre crochets. Toutes les fonctions e numriques internes sont de la forme suivante : e function ABS (n NUMBER) return NUMBER Fonction ABS CEIL COS Description Retourne la valeur absolue de n. Retourne le plus petit entier n. Retourne le cosinus de a. Langle a doit tre en radians. e Argument(s) n NUMBER n NUMBER a NUMBER
25
COSH EXP FLOOR LN LOG MOD POWER ROUND SIGN SIN SINH SQRT TAN TANH TRUNC
Retourne le cosinus hyperbolique de n. Retourne la valeur de en . Retourne le plus grand entier n. Retourne le logarithme nprien de n e e lorsque n > 0. Retourne le logarithme en base m de n lorsque m > 1 et n > 0. Retourne le reste de m/n. Retourne la valeur de mn . Retourne m arrondi ` n chires. a Retourne 1 si n < 0, 0 si n = 0 et 1 si n > 0. Retourne le sinus de a. Langle a doit tre en radians. e Retourne le sinus hyperbolique de n. Retourne la racine carre de n. e Retourne la tangente de a. Langle a doit tre en radians. e Retourne la tangente hyperbolique de n. Retourne m tronqu ` n chires. ea
n n n n
14
14.1
Complments e
Instruction DECLARE
Lutilisation de linstruction DECLARE est limite ` la cration de sous-blocs au sein de blocs PL/SQL, e a e comme montr dans lexemple suivant : e BEGIN ... <<inner>> DECLARE ... BEGIN ... END inner; ... END; Ce code utilise DECLARE pour dclarer des curseurs, des variables et des constantes locales au sous-bloc e appel inner . e
14.2
Conventions de nommage
PL/SQL permet de rfrencer tous les objets dnis (tels que des variables, des curseurs, des packages, etc.) ee e en utilisant de simples rfrences, des rfrences qualies, des rfrences distantes ou bien une combinaison ee ee e ee de rfrences qualies et de rfrences distantes. La capitalisation ne joue de rle dans aucune rfrence ee e ee o ee dobjets. Une simple rfrence ` linterface du package order_total prend la forme suivante : ee a get_order_total( ... );
26
Une rfrence qualie au mme package se prsente ainsi : ee e e e order_total.get_order_total( ... ); Une rfrence distance ` ce package est montre dans lexemple suivant : ee a e get_order_total@concepts( ... ); Finalement, en utilisant une rfrence qualie et distante, on rfrence le package order_total comme ee e ee suit : order_total.get_order_total@concepts( ... ); Les deux premi`res instances rfrencent la procdure order_total sur la machine locale. Les deux e ee e derni`res instances montrent un acc`s distant ` la procdure order_total en utilisant le lien vers la base e e a e concepts. 14.2.1 Synonymes
Pour simplier encore davantage la rfrence ` une procdure, on peut utiliser un synonyme. Il nest ee a e toutefois pas possible dutiliser des synonymes pour rfrencer des objets PL/SQL contenus dans des sousee programmes ou package. Un exemple de cration de synonyme est donn ` la section 2.2 ( cration de e e a e packages ) qui montre un exemple de script pour construire le package order_total. 14.2.2 Porte dune rfrence e ee
Une autre convention de nommage quil est utile de mentionner est la porte dune rfrence. Ceci fait e ee rfrence ` ltendue sur laquelle on peut faire rfrence ` un identicateur PL/SQL tel quune variable ou un ee a e ee a sous-programme. En termes simples, la hirarchie des portes est bloc, local, global et application. Lexemple e e suivant illustre ce point : CREATE OR REPLACE PACKAGE order_total AS PROCEDURE get_order_total ( ... ); END order_total CREATE OR REPLACE PACKAGE BODY order_total AS ot_failure EXCEPTION; ... PROCEDURE init_line_items IS i BINARY INTEGER := 0; ... BEGIN ... <<inner>> DECLARE j BINARY_INTEGER := 0; BEGIN j = i; ... EXCEPTION ... raise ot_failure; 27
END inner; ... END; END order_total; Dans cet exemple, la porte de rfrence pour la variable j est le sous-bloc interne o` la variable est dnie. e ee u e La variable i, par contre, est dnie locale ` la procdure init_line_items. Elle peut tre rfrence dans e a e e ee e le sous-bloc interne comme montr. Lexception dnie, ot_failure, est globale au corps du package et peut e e tre rfrence par tous les sous-programmes, mais pas par le code appelant. Enn, la routine dinterface e ee e get_order_total et les variables associes sont disponibles au niveau de lapplication et dans le package. e Une derni`re note sur la porte de rfrence : dans un sous-bloc, on peut dnir des identicateurs locaux e e ee e de mme noms que des identicateurs globaux. Il faut alors faire rfrence aux identicateurs globaux avec e ee un nom quali qui peut tre un bloc englobant ou un nom de sous-programme. La rfrence qualie est e e ee e alors faite en utilisant la notation . .
14.3
PL/SQL supporte ` la fois des conversions explicites et implicites de types de donnes. Les conversions a e explicites se produisent en employant une fonction interne, telle que la fonction TO_NUMBER dcrite prcdeme e e ment. Les conversions se produisent au moment de la compilation lorsquun type de donnes est fourni et un e autre type de donnes est attendu. Cette caractristique de PL/SQL permet de se reposer sur le compilateur e e plutt que dutiliser des routines de conversion explicites. Considrons linstruction SQL suivante : o e SELECT SUM(grand_total) FROM order WHERE order_date < 10-SEP-95; Dans ce cas, la colonne order_date est stocke sous la forme du type DATE et elle est compare ` 10e e a SEP-95, qui est une valeur littrale CHAR. PL/SQL eectue une conversion implicite de ce littral vers le type e e DATE lorsque la procdure contenant ce SELECT est compile. e e
14.4
Une autre utilisation courante de procdures PL/SQL est la cration de triggers (dclencheurs) de bases de e e e donnes. Les triggers sont des packages qui se dclenchent automatiquement lorsquune table dune base de e e donnes satisfait certains crit`res apr`s une opration SQL. Par consquent, les triggers de bases de donnes e e e e e e ne sont pas rfrencs explicitement par dautres procdures ou applications. ee e e Il est possible de lier jusqu` 12 triggers de bases de donnes a une table de donne. a e ` e Il y a trois parties distinctes ` considrer lors de la construction dun trigger. Il y a tout dabord lva e e e nement qui cause le dclenchement du trigger. Le dclenchement conduit ` lexcution de laction que lon e e a e peut considrer comme le code du trigger. Enn, il faut considrer les contraintes optionnelles que lon peut e e souhaiter placer sur le trigger. Voyons de plus pr`s comment les triggers sont construits. e Tout comme les packages, tous les triggers suivent une forme de dveloppement standard. Ce qui suit est e un exemple de cration de trigger : e CREATE TRIGGER name (vnement dclenchant le trigger) e e e ... (contrainte optionnelle du trigger) BEGIN (action du trigger) END; Comme le montre cet exemple, tous les triggers commencent par linstruction CREATE TRIGGER qui est le point dentre du trigger de nom name. Lvnement dclencheur du trigger commence avec un mote e e e cl pour spcier quand le trigger doit se dclencher. Cette section du code identie lopration SQL qui e e e e
28
passe le contrle au code de laction SQL. Toute contrainte sur lopration SQL est identie dans la zone de o e e spcication optionnelle du trigger. e Si lon nest pas propritaire de la table dans laquelle on cre le trigger, il faut avoir les privil`ges ALTER e e e ou ALTER ANY TABLE sur la table. Un autre privil`ge qui est ncessaire est CREATE TRIGGER, quelle que soit e e la table dans laquelle le trigger est cr. ee Lexemple suivant illustre la cration et lutilisation dun trigger : e CREATE TRIGGER check_order_total AFTER UPDATE OF order_total ON order FOR EACH ROW WHEN (new.status = NEW) BEGIN IF :new.order_total = 0 THEN INSERT INTO order_log values(:new.order); UPDATE order SET :new.status = ERR; END IF; END; Cet exemple montre que la spcication de lvnement trigger commence avec un mot-cl, ici AFTER, e e e e qui dtermine quand le trigger doit tre dclench. Linstruction FOR EACH ROW cause le dclenchement du e e e e e trigger une fois pour chaque ligne au lieu dune fois par table comme cest le cas par dfaut. Une contrainte e du dclenchement est que ltat (status) de la commande mise ` jour doit tre NEW. Laction du trigger e e a e consiste ` insrer une ligne dans la table order_log et de mettre ` jour ltat de la commande ` ERR. a e a e a Un nom corrl tel que :new fait rfrence ` des valeurs de colonnes nouvellement mises ` jour. On peut ee ee a a aussi rfrencer danciennes valeurs dune colonne qui change. Comme indiqu, on nutilise pas le : dans ee e le code des contraintes du trigger. Il nest pas possible dutiliser des commandes COMMIT, ROLLBACK ou SAVEPOINT dans des triggers.
14.5
14.5.1
La commande RAISE a dej` t illustre pour lever des exceptions dans du code, mais RAISE peut aussi aee e tre utilis pour relancer une exception. Considrons lexemple suivant : e e e CREATE OR REPLACE PACKAGE order_total AS ot_failure EXCEPTION; ... BEGIN ... BEGIN ... if g_recip_counter > max_lines then RAISE ot_failure; end if; EXCEPTION when OT_FAILURE then ... RAISE; END; ... EXCEPTION when OT_FAILURE then 29
... END; END order_total; Dans cet exemple, lexception est leve dans un sous-bloc avec une dnition de handler dexception e e ot_failure. Apr`s le traitement de cette erreur au sein du handler, lexception est ` nouveau leve pour e a e un traitement ultrieur dans le bloc de la procdure principale. Ceci est accompli avec un autre handler e e dexception ot_failure. 14.5.2 Poursuite de lexcution e
Apr`s la leve dune exception dans un sous-bloc PL/SQL, il est possible de continuer lexcution avant e e e de sortir du bloc conducteur. Il faut placer le code excutable dans le bloc conducteur apr`s le handler e e dexception. Ce qui suit est une illustration de cette technique : <<outer>> BEGIN ... <<inner>> BEGIN ... if g_recip_counter > max_lines then raise ot_failure; end if; EXCEPTION when OT_FAILURE then ... END inner; UPDATE order SET status = SU; INSERT INTO suspense_queue VALUES (order,g_out_msg); EXCEPTION ... END outer; Cet exemple montre que lexception a t traite dans le sous-bloc interieur au moment o` le contrle a ee e u o t pass au bloc conducteur externe. Au moment o` le handler dexception interne sest achev, lexcution ee e u e e a repris avec la commande UPDATE dans le bloc externe. De cette mani`re, lexcution de la procdure peut e e e continuer apr`s la rencontre dune erreur qui autrement serait fatale. e 14.5.3 Rexcution de transactions e e
Une autre mthode pour poursuivre lexcution dune procdure apr`s la leve dune exception est connue e e e e e sous le nom de rexcution de transaction. La technique est similaire ` la poursuite dune excution apr`s e e a e e la leve dune exception en ce que la transaction a ressayer doit exister dans le sous-bloc. En utilisant des e e contrles de boucles itratifs, on peut rpter une transaction aussi souvent que souhait apr`s la leve dune o e e e e e e exception. Ce qui suit illustre cette technique : BEGIN ... FOR i in 1..10 LOOP ... BEGIN SAVEPOINT update_order (transactions SQL)
30
COMMIT; EXIT; EXCEPTION WHEN ... THEN ROLLBACK to update_order (correction des probl`mes des donnes) e e ... END; END LOOP; END; Sous le contrle de la boucle FOR, les transactions SQL peuvent tre essayes au total dix fois avant o e e que lexcution de la procdure ne soit termine. SAVEPOINT update_order est le point de retour pour des e e e transactions qui ont chou. Si une erreur est rencontre durant la phase de transactions SQL de ce sous-bloc, e e e le contrle est transfr au handler dexceptions qui essaie de rsoudre les probl`mes de donnes. Apr`s o ee e e e e lexcution du handler derreur, le contrle est transfr ` la boucle FOR pour une autre passe. e o eea
14.6
Les structures suivantes sont rarement utilises mais sont quelquefois ncessaires. e e 14.6.1 Instruction EXIT
Linstruction EXIT a dj` t mentionne comme un moyen de sortir dune boucle FOR. Cette instruction eaee e peut aussi tre utilise lors du ressai de transactions apr`s la leve dexceptions. Dans ce sens, EXIT procure e e e e e un mcanisme pour le transfert inconditionnel du contrle dun point du code ` un autre. e o a 14.6.2 Contrle squentiel o e
Lutilisation de contrle squentiel dans PL/SQL nest pas un lment essentiel au dveloppement de bon o e ee e code. Toutefois, il est utile de mentionner cette technique dans une description compl`te du langage. Deux e commandes sont disponibles pour le contrle squentiel : GOTO et NULL. o e GOTO est une commande de branchement inconditionnelle qui transf`re le contrle ` une tiquette dnie e o a e e dans la porte de la logique de branchement. Ltiquette doit prcder une commande excutable ou dnir e e e e e e un bloc PL/SQL comme illustr dans lexemple suivant : e <<count_lines>> for i in 1..g_line_counter LOOP ... if i>max_lines then GOTO clean_up; end if; ... end LOOP init_lines; <<clean_up> g_recip_counter = i-1; ... Dans cet exemple, le branchement conditionnel transf`re le contrle ` ltiquette clean_up pour un e o a e traitement ultrieur. Lutilisation de la commande GOTO nest pas conseille car elle peut conduire ` du code e e a non structur. Dautres constructions de PL/SQL permettent dcrire du code qui est plus facile ` comprendre e e a et maintenir. Surtout limit ` lamlioration de la lisibilit du code, la commande NULL est un moyen de montrer que ea e e tous les choix possibles ont t considrs. NULL est considr comme une commande excutable. ee ee ee e if g_recip_counter > max_lines then 31
g_recip_counter = max_lines; else NULL; end if; Cet exemple utilise NULL pour montrer quil ny a rien a faire si g_recip_counter est ` max_lines. De mani`re vidente, ce code peut tre achev sans la clause ELSE mais le fait dutiliser NULL montre que e e e e dautres options ont t considres. ee ee
32