Vous êtes sur la page 1sur 44

PL/SQL

curseur trigger

PL/SQL versus SQL


PL/SQL : langage procdural d'Oracle tend SQL (langage ensembliste) instructions SQL intgres dans PL/SQL instructions spcifiques PL/SQL

Instructions SQL intgres dans PL/SQL


instructions du LID : SELECT instructions du LMD : INSERT, UPDATE, DELETE instr. du langage de contrle des transactions (LCT) : COMMIT, ROLLBACK, SAVEPOINT, fonctions TO_CHAR, TO_DATE, UPPER, SUBSTR,

Instructions spcifiques PL/SQL


dfinition de variables traitements conditionnels traitement rptitifs (ou boucles) traitement des curseurs traitement des erreurs

Programme PL/SQL
unit de base : le bloc PL/SQL n'interprte pas une commande mais un ensemble de commandes contenues dans un bloc PL/SQL

Structure d'un bloc PL/SQL


[DECLARE
/* dclaration de variables, constantes, exceptions, curseurs */ ]

BEGIN [<<nom_bloc>>]
/* instructions SQL et PL/SQL */

[EXCEPTION
/* traitement des exceptions (des erreurs) */ ]

END [nom_bloc] ;

les sections DECLARE et EXCEPTION sont facultatives chaque instruction, de n'importe quelle section est termine par un ; dans la section BEGIN, possibilit de sous-blocs (imbrication de blocs) aucune instruction du LCD n'est autorise ( CREATE, ALTER, DROP TABLE) traitement spcial de l'instruction SELECT

possibilit de placer des commentaires


-- commentaire sur une ligne /* commentaire sur plusieurs lignes */

pas de distinction entre maj. et min. pour tre excut, le programme doit tre suivi
une ligne avec un point et une ligne avec une instruction RUN

le programme peut tre


directement tap sur une ligne de commande ou crit dans un fichier puis charg

Variables
pour transmettre des donnes entre un programme PL/SQL et la base de donnes Variables : locales PL/SQL de l'environnement extrieur :
SQL*FORMS, PRO*, SQL*Plus

Variables locales PL/SQL


Types autoriss : type SQL pour les attributs d'une relation
char, varchar2, number, blob, clob, date, rowid

type PL/SQL :
boolean (valeur true, false ou null),

type du dictionnaire de donnes (type d'un attribut, d'un n-uplet de la base, d'une autre variable)

Variables : dfinition
Dans la partie DECLARE avec la syntaxe: pour des types "simples"
nom_var [CONSTANT] type_var [[NOT NULL] := exp] ;

pour des types "structurs"


TYPE nom_type IS RECORD ( nom_champ1 type_champ1 [[NOT NULL] := exp] [,] ) ; nom_var type_var ;

variable de mme type ou structure que celle d' une colonne d'une table da la base
nom_var table.colonne%TYPE ;

une ligne d'une table


nom_var table%ROWTYPE ;

une variable prcdemment dfinie


nom_var2 nom_var1%TYPE ;

Variable : initialisation, visibilit


l'initialisation peut se faire par
oprateur := dans les sections DECLARE, BEGIN et EXCEPTION ordre SELECT INTO dans la section BEGIN traitement d'un curseur dans la section BEGIN

visibilit
dans le bloc o elle a t dclare dans les blocs imbriqus (si non redfinie)

Commande SELECT
syntaxe
SELECT col1, col2 INTO var1, var2 FROM table [] ;

rgle
clause INTO : obligatoire le SELECT doit obligatoirement ramener une seule ligne et une seule, sinon erreur (plusieurs lignes : emploi de curseur)

Traitement conditionnel
Syntaxe : IF condition THEN instructions [ELSE instructions] END IF; IF imbriqus autoriss oprateurs utiliss dans la cd identiques ceux de SQL :
=, <, >, !=, <=, >= IS [NOT] NULL, BETWEEN, LIKE, AND, OR,

DECLARE emploi char(10) ; nom varchar2(15) := 'Miller' ; mes char(30) ; BEGIN select job into emploi from emp where ename = nom ; if emploi is null then mes := nom || ' n''a pas d"emploi' ; elsif emploi = 'Salesman' then update emp set com = 1000 where ename = nom ; mes := nom || ' commission modifie' ; else update emp set com = 0 where ename = nom ; mes := nom || ' pas de commission' ; end if; insert into resultat values (mes) ; commit; END;

Traitements rptitifs
boucle de base : LOOP boucle FOR boucle WHILE

Boucle : LOOP
[ <<label>> ] LOOP instructions; END LOOP [ label ] ; sortie de la boucle par la commande EXIT [ label ] [ WHEN condition ] o label est le nom de la boucle

exemple
DECLARE nbre number(2) := 1 ; BEGIN LOOP insert into resultat values (nbre); nbre := nbre +1 ; exit when nbre > 10 ; END LOOP ; END ;

Boucle : FOR
[ << label >> ] FOR indice IN [ REVERSE ] exp1 .. exp2 LOOP instructions ; END LOOP [ label ] ; Rgles : dclaration implicite de la variable indice exp1, exp2 : constantes, expressions ou variables sans REVERSE : indice varie de exp1 exp2, pas de 1 avec REVERSE : indice varie de exp2 exp1, pas de -1

FOR : exemple
DECLARE fact number := 1 ; BEGIN FOR i IN 1..9 LOOP fact := fact * i ; END LOOP; insert into resultat values( fact, 'factorielle de 9' ) ; END;

Boucle : WHILE
[ << label>> ] WHILE condition LOOP instructions ; END LOOP [ label ] ;

condition : combinaison d'expressions, oprateurs : <, >, =, !=, AND, OR, LIKE,

WHILE : exemple
DECLARE reste number := 7324 ; BEGIN WHILE reste >= 9 LOOP reste := reste - 9 ; END LOOP; insert into resultat values(reste,'reste divison 7324 par 9') ; END;

CURSEUR
Zone de mmoire de taille fixe, utilise par le noyau d'Oracle pour analyser et interprter tout ordre SQL. Les statuts d'excution de l'ordre se trouvent dans le curseur. curseur implicite : cr et gr par Oracle chaque ordre SQL curseur explicite : cr et gr par l'utilisateur afin de pouvoir traiter un SELECT qui retourne plusieurs lignes

Curseur explicite
L'utilisation d'un curseur explicite ncessite 4 tapes : 1. 2. 3. 4. dclaration du curseur ouverture du curseur traitement des lignes fermeture du curseur

Dclaration d'un curseur


Dans la section DECLARE du bloc avec la syntaxe : CURSOR nom_curseur IS instruction_select ; Exemple : DECLARE CURSOR dpt IS SELECT ename, sal from emp where dptno = 10 ; BEGIN END ;

Ouverture d'un curseur


Aprs avoir dclar le curseur, il faut l'ouvrir dans la section excutable (BEGIN) afin de faire excuter l'ordre SELECT : OPEN nom_curseur ; Consquences : allocation mmoire du curseur analyse de l'instruction SELECT positionnement des verrous ventuels (si SELECT FOR UPDATE)

Traitement des lignes


Aprs l'excution du SELECT, les lignes ramenes sont traites une par une, la valeur de chaque colonne du SELECT doit tre stocke dans une variable rceptrice. FETCH nom_curseur INTO liste_variables ; FETCH ramne une seule ligne ; pour traiter n lignes, prvoir une boucle

Fermeture du curseur
Aprs le traitement des lignes, pour librer la place mmoire. CLOSE nom_curseur ;

DECLARE CURSOR dpt_10 IS SELECT ename, sal FROM emp WHERE deptno=10 order by sal ; nom emp.ename%TYPE ; salaire emp.sal%TYPE ; BEGIN OPEN dpt_10 ; LOOP FETCH dept_10 INTO nom, salaire ; IF salaire > 2500 THEN insert into resultat values (nom, salaire) ; END IF; EXIT WHEN salaire = 5000 ; END LOOP ; CLOSE dpt_10 ; END;

Attributs d'un curseur


indicateurs sur l'tat d'un curseur : %FOUND %NOTFOUND %ISOPEN %ROWCOUNT boolen boolen boolen donne numrique

curseur implicite : SQL% curseur explicite : nom_curseur%

SQL% %FOUND insert, update, delete : 1 ligne traite select into : 1 seule ligne insert, update, delete , select into : 0 ligne false (curseur toujours ferm aprs utilisation)

nom_curseur% dernier FETCH a ramen 1 ligne dernier FETCH n'a pas ramen de ligne true si curseur ouvert nime ligne traite par le FETCH

%NOTFOUND %ISOPEN

%ROWCOUNT insert, update, delete : nombre de lignes traites select into : valeur 0,1ou 2 si 0,1, 1 ligne(s) traite(s)

Ecriture simplifie : dclaration de variables


Dclaration implicite d'une structure dont les lments sont d'un type identique aux colonnes ramens par le curseur : DECLARE CURSOR nom_curseur IS instruction_select ; nom_structure nom_curseur%ROWTYPE ; BEGIN FETCH nom_curseur INTO nom_structure ;

DECLARE CURSOR c1 IS select ename, sal+NVL(comm,0) saltot FROM emp ; c1_res c1%ROWTYPE ; BEGIN OPEN c1 ; LOOP FETCH c1 INTO c1_rec ; EXIT WHEN c1%NOTFOUND ; IF c1_rec.saltot > 2000 THEN insert into temp values (c1_rec.ename, c1_rec.saltot) ; END IF ; END LOOP ; CLOSE c1 ; END;

Ecriture simplifie : curseurs et boucles


DECLARE DECLARE CURSOR nom_c IS select ; CURSOR nom_c IS select ; nom_r nom_c%ROWTYPE ; BEGIN gnration BEGIN FOR nom_r IN nom_c implicite OPEN nom_c ; LOOP LOOP /* traitement */ FETCH nom_c INTO nom_r ; END LOOP ; EXIT WHEN nom_c%NOTFOUND ; /* traitement */ END LOOP ; CLOSE nom_c ;

Ecriture simplifie : curseurs et boucles


Dclaration du curseur dans la boucle FOR FOR nom_rec IN (SELECT ) LOOP traitement ; END LOOP ; Syntaxe qui vite la dclaration du curseur.

Curseur paramtr
Pour utiliser un mme curseur avec des val. diffrentes, dans un mme bloc PL/SQL DECLARE CURSOR nom_c (par1 type, par2 type,) IS ordre_select ; BEGIN OPEN nom_c(val1, val2,) ;

Type : char, number, date, boolean SANS spcifier la longueur. Passage des valeurs des paramtres l'ouverture du curseur.

Exemple : recherche des n plus gros salaire en tenant compte des doublons

DECLARE CURSOR grosal IS select distinct sal from emp order by sal desc ; CURSOR c1(psal number) IS select ename, sal, empno from emp where sal = psal; BEGIN FOR vgrosal IN grosal LOOP EXIT WHEN grosal%rowcount > &Nombre ; -- Nombre est une variable SQL*Plus FOR employe IN c1(vgrosal.sal) LOOP insert into resultat values ( employe.sal, employe.ename || ' de numero : ' || to_char(employe.empno) ) ; END LOOP; END LOOP; END;

CURRENT OF
CURRENT OF permet d'accder directement en modification ou suppression du n-uplet rcupr par FETCH. Il faut au pralable rserver les lignes lors de la dclaration du curseur par un verrou d'intention (SELECT FOR UPDATE [OF nom_colonne,] ).

Exemple : augmenter les employs dont le salaire est suprieur 1500. DECLARE CURSOR c1 IS select ename, sal from emp FOR UPDATE OF sal ; BEGIN FOR c1_rec IN c1 LOOP IF c1_rec.sal > 1500 THEN insert into resultat VALUES (c1_rec.ename, c1_rec.sal * 1.3) ; update emp set sal = sal * 1.3 WHERE CURRENT OF c1 ; END IF; END LOOP; END;

Gestion des erreurs


Section EXCEPTION : pour effectuer un traitement appropri aux erreurs survenues lors de l'excution d'un bloc PL/SQL. Types d'erreurs : erreur interne Oracle (SQLCODE != 0) erreur programme utilisateur Rgles : dfinir et donner un nom chaque erreur associer le nom de l'erreur la section EXCEPTION dans la partie DECLARE dfinir le traitement effectuer dans la partie EXCEPTION

Anomalie prog. utilisateur : syntaxe


DECLARE nom_erreur EXCEPTION ; BEGIN IF (anomalie) THEN RAISE nom_erreur ; EXCEPTION WHEN nom_erreur THEN (traitement) ; Note : Sortie du bloc aprs excution du traitement.

DECLARE pas_comm EXCEPTION ; salaire emp.sal%TYPE ; commi emp.comm%TYPE ; numero emp.empno%TYPE; BEGIN select sal, comm, empno into salaire, commi, numero from emp where empno := :num_emp ; /* num_emp fait rf. une var. extrieure au bloc PL/SQL */ IF commi = 0 or commi is null THEN RAISE pas_comm ; ELSE /* traitement */ END IF ; EXCEPTION WHEN pas_comm THEN insert into resultat values (numero, salaire, 'pas de commission'); END.

Erreur

Oracle : syntaxe

DECLARE nom_erreur EXCEPTION ; PRAGMA EXCEPTION_INIT(nom_erreur, code_erreur); BEGIN ds que l'erreur Oracle est rencontre, passage automatique la section EXCEPTION pour raliser le traitement appropri EXCEPTION WHEN nom_erreur THEN (traitement) ; [WHEN OTHERS THEN (traitement) ;] ; Note : Sortie du bloc aprs excution du traitement. Il existe des erreurs prdfinies pas besoin de les dclarer, ni de les associer un code erreur

Vous aimerez peut-être aussi