4. PL/SQL dans le monde ORACLE
disponible dans les outils de développement PL/SQL developer,
SQL*plus, Sql*Forms,etc
PL/SQL est un langage algorithmique complet.
PL/SQL ne comporte pas d’instructions du LDD (ALTER, CREATE,
RENAME) ni les instructions de contrôle comme GRANT et REVOKE.
4
5. Instructions SQL intégrées dans PL/SQL
La partie LID (select)
La partie LMD (insert, update, delete)
La partie gestion de transactions (commit, rollback, savepoint,...)
Les fonctions (to_char, to_date, upper, substr, round, ...)
+ Une partie procédurale (IF, WHILE, …)
Instructions spécifiques à PL/SQL:
Défintion de variables
Traitements conditionnels
Traitements répétitifs
Traitement des curseurs
Traitement des erreurs
5
6. PLSQL
/* Déclaration des variables, des types, des
curseurs, fonctions et procédures */
/* Instructions PL/SQL ; tout instruction est
terminée par ; */
/* Traitement des erreurs */
Les blocs peuvent être imbriqués.
Les programmes PL/SQL sont structurés en blocs
6
7. PLSQL
identificateur [CONSTANT] type [:= valeur];
DECLARE
nom CHAR(15);
numero NUMBER;
date_jour DATE;
salaire NUMBER(7,2);
pi constant Number(4,2):=3.14
7
8. Fast example
Afficher la valuer d’une variable
8
Declare
var1 number := 10;
Begin
Dbms_Output.Put_Line('La valeur de la variable = ' || var1);
End;
9. CREATE TABLE utilisateur
(
U_ID INT PRIMARY KEY NOT NULL,
nom VARCHAR(100),
prenom VARCHAR(100),
ville VARCHAR(100)
);
CREATE TABLE commande
(C_ID INT PRIMARY KEY NOT NULL,
Prix Number(20,0),
Quantity Number(3,0),
Cmd_date date,
Id_utilisateur INT NOT NULL
);
Creation des tables
10. Insertion des enregistrements pour la table
utilisateur et commande
INSERT ALL
Into commande (c_id, prix,quantity,cmd_date, id_utilisateur) VALUES
(200, 20000,4,'01-04-2005',11)
Into commande (c_id, prix,quantity,cmd_date, id_utilisateur) VALUES
(201, 10000,2,'01-04-2015',12)
Into commande (c_id, prix,quantity,cmd_date, id_utilisateur) VALUES
(202, 40000,10,'19-05-2018',15)
Into commande (c_id, prix,quantity,cmd_date, id_utilisateur) VALUES
(203, 10000,2,'01-04-2017',13)
Into commande (c_id, prix,quantity,cmd_date, id_utilisateur) VALUES
(204, 10000,2,'10-09-2017',14)
SELECT 1 FROM DUAL;
11. Insertion des enregistrements pour la table
utilisateur et commande
11
INSERT ALL
INTO utilisateur(U_id, nom,prenom, ville) VALUES (10, 'Ahmed', 'BenAli',
'Ouargla')
INTO utilisateur(U_id, nom, prenom,ville) VALUES (11, 'Mourad',
'Mosbah','paris')
INTO utilisateur(U_id, nom, prenom, ville) VALUES (12, 'Meriem',
'BenMohamed', 'Madrid')
INTO utilisateur(U_id, nom, prenom, ville) VALUES (13, 'Asma',
'BenMohamed', 'Rabat')
INTO utilisateur(U_id, nom, prenom, ville) VALUES (14, 'soumia', 'BenAli',
'Ouargla')
SELECT 1 FROM DUAL;
14. Les types les plus populaires
Le type de texte
Number
Integer
Float
Double
Real
Varchar2
14
Les types de texte
15. Le type de données %type
Le type de données (%type)
Declare
v_Name utilisateur.nom%Type;
v_util_id utilisateur.U_id%Type :=11;
Begin
Select u.nom
Into v_Name
From utilisateur U
Where U.U_ID = v_util_id;
----
Dbms_Output.Put_Line('v_Name= ' || v_Name);
End;
15
16. Le type de données %Rowtype
Declare
v_util_id utilisateur.U_id%Type :=11;
-- Declare a variable
-- Is row type of utilisateur table.
v_row utilisateur%Rowtype;
Begin
Select * Into v_row From utilisateur U Where U.U_Id = v_util_Id;
----
Dbms_Output.Put_Line(' Name= ' || v_row.nom);
Dbms_Output.Put_Line('Ville= ' || v_row.ville);
Exception
When No_Data_Found Then
-- When SELECT .. INTO statement returns nothing.
Dbms_Output.Put_Line('No data with U_id= ' || v_util_Id);
End;
16
17. Le type de données Record
17
-- Declare your data type.
TYPE Type_Record_Name IS
RECORD (
Col1 Datatype1 [NOT NULL{:=|DEFAULT} expression],
Col2 Datatype2 [NOT NULL{:=|DEFAULT} expression],
...
);
-- Variable declaration using data type:
variable_name Type_Record_Name;
18. Le type de données record
Declare
v_util_Id Utilisateur.U_Id%Type := 11;
-- Define Record data type has 3 column.
Type U_Name_Type Is Record(
U_First_Name Utilisateur.nom%Type
,U_Last_Name Utilisateur.prenom%Type
,U_Full_Name Varchar2(100));
----
-- Define a variable of type U_Name_Type
v_util U_Name_Type;
Begin
Select U.nom
,U.prenom
,U.nom || ' ' || U.prenom
Into v_util
From Utilisateur U
Where U.U_Id = v_util_Id;
----
Dbms_Output.Put_Line(' First_Name= ' || v_util.U_First_Name);
Dbms_Output.Put_Line(' Last_Name= ' || v_util.U_Last_Name);
Dbms_Output.Put_Line(' Full_Name= ' || v_util.U_Full_Name);
Exception
When No_Data_Found Then
-- When SELECT .. INTO statement return nothing.
Dbms_Output.Put_Line('No data with U_id= ' || v_util_Id);
End;
18
19. Le type de données table
Le type de données TABLE est similaire a array.
Les index sur la table sont pas forcement consecutives. For example, TABLE has three elements with
indexes of 1, 3, 5.
19
20. Le type de données table
20
-- Syntax:
TYPE <Table_Name>
IS TABLE OF <Data_Type> [NOT NULL]
INDEX BY BINARY_INTEGER;
-- Example
-- Define TABLE data type, contains elements of type VARCHAR2 (50)
TYPE My_Tbl
IS TABLE OF Varchar2(50)
INDEX BY BINARY_INTEGER;
21. Attributs de type table
21
Nom de fonction/Attribut Définition Exemple
• DELETE Supprime des lignes dans un tableau v_tbl.delete(3);
• EXISTS Renvoie TRUE si l'entrée spécifiée existe dans le tableau. v_e:= v_tbl.exists(3);
• COUNT Renvoie le nombre de lignes dans le tableau. v_count:=v_tbl.count;
• FIRST Renvoie l'index de la première ligne dans le tableau. v_first_idx:=v_tbl.first;
• LAST Renvoie l'index de la dernière ligne dans le tableau. v_last_idx:=v_tbl.last;
• NEXT Renvoie l'index de la ligne suivante dans le tableau après la ligne spécifiée. v_idx:= v_tbl.next(2);
• PRIOR Renvoie l'index de la ligne précédente dans le tableau avant. v_idx:=v_tbl.prior(2);
22. Example with Table
Declare
-- Define TABLE data type:
Type My_Tbl Is Table Of Varchar2(50) Index By Binary_Integer;
-- Define varable of type My_Tbl.
v_utils My_Tbl;
Begin
v_utils(1) := 'One';
v_utils(2) := 'Two';
v_utils(3) := 'Three';
Dbms_Output.Put_Line('Element Count = ' || v_utils.Count);
For i In v_utils.First .. v_utils.Last Loop
Dbms_Output.Put_Line('Element at ' || i || ' = ' || v_utils(i));
End Loop;
End;
22
23. Type de données Varray
-- Define Array data type
TYPE <varray_type_name>
IS VARRAY(n)
OF <element_type>;
23
-- declare an array, declare an array of 5 elements, and elements of
type VARCHAR2(10);
TYPE villearray
IS VARRAY(5)
OF Varchar2(10);
Syntaxe Example
24. Type de données Varray
Declare
-- Define Array data type.
-- containing data type of VARCHAR2 (50)
Type U_Array Is Varray(5) Of Varchar2(50);
-- Define Array data type, containing data type of Integer
Type Salary_Array Is Varray(5) Of Integer;
---
v_Names U_Array;
v_Count Integer;
Begin
-- Initialize the value of array elements.
v_Names := U_Array('Mourad'
,'Ahmed'
,'Houda'
,'Noura'
,'Merieme');
-- Element count.
v_Count := v_Names.Count;
Dbms_Output.Put_Line('Count = ' || v_Count);
---
For i In 1 .. v_Count Loop
Dbms_Output.Put_Line('Uloyee = ' || v_Names(i));
End Loop;
End;
24
25. Travail demandé
Ecrire 2 scripts PL/SQL
Script 1: affiche les différentes propriétés de d’une structure tableau PL/SQL
Script 2: affiche les différentes propriétés de d’une structure varray PL/SQL
25
Modifier le script de la page 22
pour afficher les differents attributs
du type table presentés dans le
tableau a gauche
25
Nom de
fonction/Attribut
Définition Exemple
• DELETE Supprime des lignes dans un tableau v_tbl.delete(3);
• EXISTS Renvoie TRUE si l'entrée spécifiée existe dans le tableau.
v_e:=
v_tbl.exists(3);
• COUNT Renvoie le nombre de lignes dans le tableau.
v_count:=v_tbl.cou
nt;
• FIRST Renvoie l'index de la première ligne dans le tableau.
v_first_idx:=v_tbl.fi
rst;
• LAST Renvoie l'index de la dernière ligne dans le tableau.
v_last_idx:=v_tbl.la
st;
• NEXT
Renvoie l'index de la ligne suivante dans le tableau après la
ligne spécifiée.
v_idx:=
v_tbl.next(2);
• PRIOR Renvoie l'index de la ligne précédente dans le tableau avant.
v_idx:=v_tbl.prior(2
);
Exemple
Attribut count:
Dbms_Output.Put_Line('Element Count = '
|| v_utils.Count);
Exemple pour le type table
27. Boucle Loop
LOOP
-- Do something here
EXIT WHEN <Condition>;
END LOOP;
x := 0;
y:=10;
Loop
x := x + 1;
y := y - x;
Exit When x > y;
End Loop;
Ecrire un petit script qui affiche la valeur de x et y
a chaque iteration
27
28. Boucle Loop for
FOR v_Index IN <Min value> .. <Max value>
LOOP
-- Do something here
END LOOP;
Ecrire un petit script qui affiche les nombres de 1 a 10 an utilisant
la boucle for
28
32. Cursors
Cursor est un type de variable structurée qui nous permet de traiter des données
avec différentes lignes.
Le nombre de lignes dépend de l'instruction d'interrogation de données après la
ligne.
Nous manipulons Cursor dans chaque ligne de données.
Cette ligne de données est spécifiée par un curseur.
En déplaçant le curseur, nous pouvons extraire toute la donnée d'une ligne actuelle.
32
35. Etats de curseur
Attribut Signification
%isopen renvoie la valeur True si cursor s'ouvre
%notfound renvoie la valeur true s'il n'y a plus la prochaine ligne
%found renvoie la valeur true s'il existe une ligne suivante.
%rowcount renvoie le nombre row a été récupéré.
35
36. set serveroutput on;
Declare
--cursor v_cur is select CID from utilisateur
cursor v_cur is select c_id from commande where prix<15000;
v_com_id commande.c_id%type;
Begin
open v_cur;
loop
fetch v_cur into v_com_id;
exit when v_cur%notfound;
dbms_output.put_line('L’utilsateur avec ID='|| v_com_id||' a effctué des
achats <15000 DA');
end loop;
close v_cur;
End;
37. set serveroutput on;
Declare
cursor v_cur is select c_id from commande where prix<15000;
v_com_id commande.c_id%type;
Begin
open v_cur;
loop
fetch v_cur into v_com_id;
exit when v_cur%notfound;
dbms_output.put_line('L’utilsateur avec ID='|| v_com_id||' a effctué des
achats <15000 DA');
end loop;
close v_cur;
End;
38. set serveroutput on;
Declare
--cursor v_cur is select nom from utilisateur
cursor v_cur is select * from commande where prix<15000;
v_com_ligne v_cur%rowtype;
Begin
open v_cur;
loop
fetch v_cur into v_com_ligne;
exit when v_cur%notfound;
dbms_output.put_line('L’utilisateur avec ID='|| v_com_ligne.c_id||' a effctué
des achats = '||v_com_ligne.prix);
end loop;
close v_cur;
End;
39. Cursor declaration
CURSOR <Cursor_Name>
IS
<Select_Statement>
CURSOR <Cursor_Name>(<Parameter_List>)
IS
<Select_Statement>
Declare
Cursor U_Cur Is
Select U.U_ID
,U.Prenom
,U.NOM
From Utilisateur U;
declare
Cursor U_Cur(var_id Number
,var_nom varchar)
Is
Select U.U_ID
,U.NOM
,U.Prenom
,U.Ville
From utilisateur U
Where (U.U_ID = var_id Or U.U_ID Is Null)
And (U.NOM = var_nom Or U.Nom Is Null);
39
45. Declaration procedure (with parameters)
45
CREATE OR REPLACE Procedure Name(p_Param1 Varchar2, v_Param Out Varchar2)
IS|AS
-- Declare variables here
Begin
-- Do something here.
End;
46. Example
create or replace procedure show_name_par(id_ut Number) is
v_name utilisateur.nom%type;
begin
select nom into v_name from utilisateur u where u.u_id=id_ut;
dbms_output.put_line('le nom de l''utilsateur est '||v_name);
end show_name_par;
46
47. Execute procedure avec SQLDeveloper
Execute Nom_proc
Exec Nom_proc
Begin
Nom_proc
End;
47
DROP PROCEDURE <Procedure_Name>
Supprimer une procedure
48. Triggers
Définition
Les triggers sont des procédures stockées qui s’exécutent automatiquement quant
un événement se produit. En général cet événement représente une opération DML
(Data Manipulation Language ) sur une table. Les instructions DML doivent inclure
INSERT, UPDATE ou DELETE Ils permettent entre autre de contrôler les accès à la
base de données.
48
49. Triggers
Procédures simples stockées
S’exécutent implicitement lorsqu’une instruction INSERT, DELETE ou UPDATE porte
sur la table
49
50. Triggers
CREATE [OR REPALCE] TRIGGER nomtrigger
BEFORE [ AFTER] INSERT OR UPDATE OR DELETE
ON Nomdetable [FOR EACH ROW] [WHEN condition]
BLOC PL/SQL
50
51. CREATE TRIGGER nom
BEFORE DELETE OR INSERT OR UPDATE ON
tablename
[FOR EACH ROW WHEN (condition)]
DECLARE
............ <<<<déclarations>>>>
BEGIN
............
<<<< bloc d'instructions PL/SQL>>>>
END;
51
53. Triggers
Si l'option FOR EACH ROW est spécifiée, c'est un trigger ligne, sinon c'est un
trigger de table.
Doit être unique dans un même schéma, peut être le nom d'un autre objet (table,
vue, procédure) mais à éviter.
53
CREATE TRIGGER nom
BEFORE DELETE OR INSERT OR UPDATE ON tablename
[FOR EACH ROW WHEN (condition)]
DECLARE
............ <<<<déclarations>>>>
BEGIN
............
<<<< bloc d'instructions PL/SQL>>>>
END;
54. Before & After
elle précise le moment quand ORACLE déclenche le trigger,
Les triggers AFTER row sont plus efficaces que les BEFORE row parce qu'ils ne
nécessitent pas une double lecture des données.
54
55. Trigger Table
Elle comprend le type d'instruction SQL qui déclenche le trigger
DELETE, INSERT, UPDATE
On peut en avoir une, deux ou les trois.
55
56. Trigger Table
CREATE TRIGGER UT_UPDATE_SALAIRE
BEFORE UPDATE
ON commande
BEGIN
DBMS_OUTPUT.PUT_LINE(’ Avant la mise à jour de quelque commande’);
END;
56
UPDATE Commande SET prix= prix+(prix*0.1);
57. Trigger Ligne
Le trigger n'est déclenché sur une ligne que si l'expression WHEN est vérifiée
pour cette ligne.
57
58. Les noms de corrélation (OLD/New)
de triggers lignes, il est possible d’avoir accès à la valeur ancienne et la valeur
nouvelle grâce aux mots clés OLD et NEW
Il n’est pas possible d’avoir accès à ces valeurs dans les triggers de table.
58
La nouvelle valeur est appelée : new.colonne
L'ancienne valeur est appelée : old.colonne
Exemple : IF :new.prix < :old.prix then
59. Les noms de corrélation (OLD/New)
CREATE OR REPLACETRIGGER cmd_UPDATE_prix
BEFORE UPDATE ON commande
FOR EACH ROW
BEGIN
DBMS_OUTPUT.PUT_LINE(’Avant la mise à jour ’ || TO_CHAR(:OLD.prix) || ’ vers ’ ||
TO_CHAR(:NEW.prix));
END;
59
UPDATE commande SET prix= prix+(prix*0.1);
60. Les prédicats conditionnels INSERTING,
DELETING et UPDATING
Lorsqu’un trigger a plusieurs opérations déclenchantes le corps peut avoir des
prédicats conditionnels :
IF INSERTING THEN ... END IF;
IF UPDATING THEN ... END IF;
60