Académique Documents
Professionnel Documents
Culture Documents
• PL/SQL
– Langage procédural, qui intègre des ordres SQL
• SELECT, INSERT, UPDATE, DELETE
• INSERT, UPDATE, DELETE
• Gestion de transactions: COMMIT, ROLLBACK, SAVEPOINT
• Langage à part entière comprenant
– Définition de variables, constantes, expressions, affectations
– Traitements conditionnels, répétitifs
– Traitement de Curseurs
– Traitement des erreurs et d’exceptions
– Etc…
Exemple
DECARE
qty_on_hand NUMBER(5);
BEGIN
SELECT quantity INTO qty_on_hand FROM inventory
WHERE product = ‘TENNIS RACKET’
FOR UPDATE of quantity;
IF qty_on_hand > 0 THEN
UPDATE inventory SET quantity quantity – 1
WHERE product = ‘TENNIS RACKET’;
INSERT INTO purchase_record
VALUES(‘Tennis racket puchased’,SYSDATE);
ENF IF;
COMMIT;
END;
Structure
[DECLARE
--declarations de variables contantes
-- exceptions et curseurs]
BEGIN [nom-bloc]
--instructions SQL et extentions
[EXCEPTIONS
-- Traitement des exceptions]
END; ou END nombloc
Architecture
PL/SQL Engine
Declare
nom char(15);
salaire number(7,2);
embauche DATE ;
réponse boolean;
Variables sur la métabase
• Reprend
– Soit le même type qu’une colonne dans une table
– Soit la même structure qu’une ligne dans une table
– Soit le même type qu’une variable précédemment définie
• Syntaxe
nom_var1 table.colonne%TYPE
nom_var2 table%ROWTYPE
nom_vars3 nom_var1%TYPE
• Exemples:
nom emp.ename%TYPE;
enreg emp%ROWTYPE;
commi number(7,2);
Salaire commi%TYPE;
Initialisation et visibilité
• Dans la déclaration
Nom char(10) := ‘Miller’;
Reponse boolean := TRUE;
• Constantes
Pi CONSTANT number (7,2) := 3.14;
• Interdire les valeurs non renseignées: NOT NULL
Debut number NOT NULL := 10;
• L’ordre SELECT
Select col1, col2
Into var1, var2
From table
[Where condition ];
• Règle
– La clause INTO est obligatoire
– Le select ne doit ramener qu’une ligne
• Visibilité: bloc de déclaration + blocs imbriqués
Exemple
Declare
nom_emp char(15);
salaire emp.sal%TYPE
commission emp.comm%TYPE;
nom_départ char(15);
Begin
Select ename, sal, comm, dname
Into nom_emp, salaire, commission, nom_départ
From emp, dept
Where ename = ‘MILLER’ and emp.deptno = dept.deptno
…
End;
Traitements Conditionnels
IF condition THEN
instruction; … instruction;
[ELSEIF condition THEN
instruction; … instruction; ]
…
[ELSEIF condition THEN
instruction; … instruction;]
[ELSE
instruction; … instruction;]
END-IF;
• IF THEN
IF condition Then traitement ENDIF;
• Exemple:
IF sales > quota THEN
compute_bonnus(emp_id);
UPDATE payroll SET pay = pay + bonus where empno =
emp_id;
END IF;
• IF THEN ELSE
IF condition THEN
traitement1
ELSE
traitement2;
END IF;
• Exemple:
IF trans_type = ‘CR’ THEN
UPDATE accounts SET balance = balance + credit WHERE …
ELSE
UPDATE accounts SET balance = balance – debit WHERE …
END IF;
IF THEN ELSEIF
• IF condition1THEN
Traitement 1;
ELSEIF condition2 THEN
Traitement2;
ELSE
traitement3;
END IF;
• Exemple:
IF sales > 50000 THEN
bonus := 1500;
ELSEIF sales > 35000 THEN
bonus := 500;
ELSE
bonus := 100;
IF condition1 THEN IF condition1 THEN
traitement1; traitement1;
ELSE ELSEIF condition2 THEN
IF condition2 THEN traitement2;
traitement2; ELSEIF condition3 THEN
ELSE END IF;
IF condition3 THEN
traitement3;
END IF;
END IF;
END IF; Sont équivalents
Exemple
DECLARE
emploi char (10);
nom char(15) := ‘MILLER’;
ctl char(30);
BEGIN
Select job INTO emploi FROM emp WHERE ename = nom;
IF emploi is null THEN ctl := nom || ‘n’apas d’emploi ’;
ELSEIF emploi = ‘SALESMAN’
THEN update emp
set comm = 1000 where ename = nom;
ctl := nom || ‘commission modifiee’;
ELSE
update emp
set comm = 0 where ename = nom;
ctl := nom || ‘pas de commission’;
END IF;
insert into resultat values(ctl);
commit;
END;
/
Instruction GOTO
GOTO nom_étiquette;
Instruction NULL
IF (mod(i,10) = 0) THEN
i := i + 1;
else
NULL;
END IF;
Commentaires
instruction;
-- Bla bla bla
instruction
Ou avec /* Bla bla bla */
EXAMPLE 1
DECLARE
max_records CONSTANT int := 100;
i int := 1;
BEGIN
FOR i in 1.. Max_records LOOP
if (mod(i,10) = 0) then
INSERT INTO teste_table (val, current_date) values (i, SYSDATE);
else
NULL;
END IF;
END LOOP;
COMMIT;
END;
/
Exemple 2
SQL> set serveroutput on
SQL >
SQL> declare
2
2 Average_Body_Temp Patient.Body_Temp_Deg_F%type;
3
3 begin
4
4 dbms_output.enable;
5
5 select avg(Body_Temp_Deg_F) into Average_Body_Temp from Patient;
6
6 dbms_output.put_line(‘Température moyenne du corps en degrés F: ‘ ||
to_char(Average_Body_Temp,’999.99’));
7
7 end;
8/
Temperature moyenne du corps en degrés F: 99,80
Procedure PL/SQL terminée avec succès.
Imbrication de blocs
PL/SQL permet d’inclure des sous-blocs dans un bloc (pratique n’est
pas recommandé)
.Declare
x real;
Begin
… x extérieur
declare
x real;
begin
Visibilité
x intérieur
…
end;
…
End; x extérieur
Procédures
PROCEDURE nom_procédure [(argument1 … [, argumentN) ] IS
[déclarations_de_variables_locales ]
BEGIN
section_exécutable
[section_exception]
END [nom_procedure]
Begin
New_Patient_ID := ‘GG9999’;
Record_Patient_Temp_Deg_C (Nex_Patient_ID, High_Fever);
End;
/
Fonctions
Additional_Fees Course.Additional_Fees%type;
Units Cours.Units%type;
Cours_ID Course.Course_ID%type;
Begin
select Course_ID into Cours-ID
from Course
where Departement_ID = Dept_ID and additional_Fees in
(select max(Additional_Fees)
from Course where Departement_ID = Dept_ID);
return Course_ID;
End;
Begin
dbms_output.enable;
Course_ID := Max_Additional_Fees(‘ECON’);
dbms_output.put_line(‘Course_ID: ‘|| Course_ID);
End;
/
Recherche de données avec un curseur
• Definition
– Un curseur est un mécanisme permettant de rechercher un nombre
arbitraire de lignes avec une instruction SELECT.
• Deux types de curseurs:
– Le curseurs implicite: généré et géré par le noyau pour chaque
ordre SQL d’un bloc
– Le curseur explicite: généré para l’utilisateur pour traiter un ordre
SELECT qui ramène plusieurs lignes. Utilisation:
– Déclaration
– Ouverture du curseur
– Traitement des lignes
– Fermeture du curseur
Déclaration d’un curseur explicite
• Se fait dans la section Declare
• Syntaxe
cursor nom_curseur is ordre_select
• Exemple
Declare
cursor dept_10 is
select ename, sal From emp
where deptno = 10 order by sal;
Begin
…
End;
Ouverture
• L’ouverture déclanche:
– Allocation de mémoire pour le lignes du curseur
– L’analyse syntaxique et sémantique du select
– Le positionnement de verrous éventuels
• L’ouverture se fait dans la section Begin
• Syntaxe: OPEN nom_curseur;
Declare
cursor dept_10 is
select ename, sal From emp
where deptno = 10 order by sal;
Begin
…;
open dept_10;
…;
End;
Traitement de Lignes
Declare
cursor dept_10 is
select ename, sal From emp
where deptno = 10 order by sal;
nom emp.ename%TYPE;
salaire emp.sal%TYPE;
Begin
Open dept_10;
Loop
Fetch dept_10 into nom, salaire;
If salaire > 2500
(nom,salaire); then insert into résultat values
end if;
exit when salaire = 5000;
end loop;
close dept_10;
End;
Exemple
Prompt Nombre de salaires ?
Accept nombre;
Declare
Cursor c1 is select ename, sal from emp
order bay sal desc;
vename emp.ename%TYPE;
vsal emp.sal%TYPE;
Begin
open c1;
for i in 1..&nombre
loop
fetch c1 into vename, vsal;
insert into résultat values (vsal, vename);
end loop;
close c1
End;
Les attributs d’un curseur
Declare
cursor dept_10 is
select ename, sal From emp
where deptno = 10 order by sal;
nom emp.ename%TYPE;
salaire emp.sal%TYPE;
Begin
Open dept_10;
Fetch dept_10 into nom, salaire;
While dept_10%FOUND
Loop
If salaire > 2500
(nom,salaire); then insert into résultat values
end if;
Fetch dept_10 into nom, salaire;
end loop;
close dept_10;
End;
Exemple - %NOTFOUND
Declare
cursor dept_10 is
select ename, sal From emp
where deptno = 10 order by sal;
nom emp.ename%TYPE;
salaire emp.sal%TYPE;
Begin
Open dept_10;
Loop
Fetch dept_10 into nom, salaire;
Exit when dept_10%NOTFOUND;
If salaire > 2500
(nom,salaire); then insert into résultat values
end if;
end loop;
close dept_10;
End;
Exemple - %ISOPEN
Declare
cursor dept_10 is
select ename, sal From emp
where deptno = 10 order by sal;
nom emp.ename%TYPE;
salaire emp.sal%TYPE;
Begin
If not(dept_10%ISOPEN) the Open dept_10; end if;
Loop
Fetch dept_10 into nom, salaire;
Exit when dept_10%NOTFOUND;
If salaire > 2500
(nom,salaire); then insert into résultat values
end if;
end loop;
close dept_10;
End;
Exemple - %ROWCOUNT
Declare
cursor dept_10 is
select ename, sal From emp
where deptno = 10 order by sal;
nom emp.ename%TYPE;
salaire emp.sal%TYPE;
Begin
Open dept_10;
Loop
Fetch dept_10 into nom, salaire;
Exit when dept_10%NOTFOUND or dept_10%ROWCOUNT > 15;
If salaire > 2500
then insert into résultat values (nom,salaire);
end if;
end loop;
close dept_10;
End;
Gestion des Erreurs
• Section Exception
• Anomalie programmeur
• Erreur Oracle
Section Exception
• Notion d’exception: traitements d’erreurs
• Types d’erreurs:
– Erreurs internes Oracle (Sqlcode <> 0)
– Erreurs programme utilisateur
• Règles à respecter
– Définir et donner un nom à chaque erreur
– Associer ce nom à la section Exception (partie declare)
– Définir la traitement dans la partie Exception
Gestion des Exceptions
• Syntaxe
EXCEPTION
WHEN nom_exception1 THEN
instructions_PL_SQL;
…
WHEN nom_exceptionN Then
instructions PL/SQL;
…
[WHEN OTHERS THEN
instrctions_PL/SQL;]
END;