Télécharger la présentation
La présentation est en train de télécharger. S'il vous plaît, attendez
Publié parJacques Marier Modifié depuis plus de 9 années
1
CHAPITRE 4 PL/SQL Langage SQL en mode procédural (PL/SQL):
Introduction et Blocs PL/SQL PL/SQL Déclaration des variables , boucle, alternatives, affichage , GOTO La gestion des exceptions Curseurs Procédures et fonctions stockées Les Déclencheurs (Triggers) Groupement de procédures et packages
2
Langage PL/SQL Pourquoi PL/SQL ? PL/SQL = PROCEDURAL LANGUAGE/SQL
SQL est un langage non procédural Les traitements complexes sont parfois difficiles à écrire si on ne peut utiliser des variables et les structures de programmation comme les boucles et les alternatives On ressent vite le besoin d’un langage procédural pour lier plusieurs requêtes SQL avec des variables et dans les structures de programmation habituelles ▴
3
Langage PL/SQL Principales caractéristiques
Extension de SQL : des requêtes SQL cohabitent avec les structures de contrôle habituelles de la programmation structurée (blocs, alternatives, boucles). La syntaxe ressemble au langage Ada ou Pascal. Un programme est constitué de procédures et de fonctions. Des variables permettent l’échange d’information entre les requêtes SQL et le reste du programme ▴
4
Langage PL/SQL Utilisation de PL/SQL
PL/SQL peut être utilisé pour l’écriture des procédures stockées et des triggers. (Oracle accepte aussi le langage Java) PL/SQL convient aussi pour écrire des fonctions utilisateurs qui peuvent être utilisées dans les requêtes SQL (en plus des fonctions prédéfinies). ▴
5
Langage PL/SQL Utilisation de PL/SQL (suite)
Le PL/SQL peut être utilisé sous 3 formes : 1 un bloc de code, exécuté comme une unique commande SQL, via un interpréteur standard (SQLplus ou iSQL*PLus) 2 3 un fichier de commande PL/SQL un programme stocké (procédure, fonction, trigger) ▴
6
Langage PL/SQL Blocs Un programme est structuré en blocs d’instructions de 3 types : procédures ou bloc anonymes, procédures nommées, fonctions nommées. Un bloc peut contenir d’autres blocs. Considérons d’abord les blocs anonymes.
7
Langage PL/SQL Structure d’un bloc anonyme
DECLARE −- d e f i n i t i o n d e s v a r i a b l e s BEGIN Seuls BEGIN et END sont obligatoires −− c o d e du programme EXCEPTION Les blocs se terminent par un ; −− c o d e de g e s t i o n d es erreurs END ; Faisons ensemble un exemple sur SQL developer set serveroutput on; declare n1 number; n2 number; r number; begin n1:=0; n2:=6; r:=n2/n1; dbms_output.put_line('rrr est egale à : '||r); exception when zero_divide then dbms_output.put_line('ERROR §§§'); end ;
8
Langage PL/SQL Commentaires -- Pour une fin de ligne /* Pour plusieurs lignes */
9
Langage PL/SQL Exemple de base d’un bloc PL/SQL set serveroutput on;
declare n1 number; n2 number; r number; begin n1:=0; n2:=6; r:=n2/n1; dbms_output.put_line('rrr est egale à : '||r); exception when zero_divide then dbms_output.put_line('ERROR §§§'); end ;
10
Langage PL/SQL Déclaration, initialisation des variables
Identificateurs Oracle : 30 caractères au plus, commence par une lettre, peut contenir lettres, chiffres,_ $ et # pas sensible à la casse. Portée habituelle des langages à blocs Doivent être déclarées avant d’être utilisées
11
Langage PL/SQL Exemples Déclaration et initialisation Initialisation
Syntaxe : Nom_variable type_variable := valeur; Initialisation Nom_variable := valeur; Déclarations multiples interdites. Exemples age integer; nom varchar(30); dateNaissance date; ok boolean := true; ▴
12
Langage PL/SQL Plusieurs façons d’affecter une valeur à une variable
Opérateur d’affectation n:= Directive INTO de la requête SELECT. Exemples dateNaissance := to_date(’10/10/2004’,’DD/MM/YYYY’); SELECT nom INTO v_nom FROM employees WHERE id_employees = 509; V_sal:= 4000 Select departement_id into det_id from employees V_sal:= 4000 Attention Pour eviler les conflits de nommage, préfixer les variables PL/SQL par v_
13
Langage PL/SQL SELECT ...INTO ... Instruction :
SELECT expr1,expr2, ...INTO var1, var2, ... Met des valeurs de la BD dans une ou plusieurs variables var1, var2, ... Le SELECT ne doit retourner qu’une seule ligne Avec Oracle il n’est pas possible d’inclure un SELECT sans INTO dans une procédure. Pour retourner plusieurs lignes, voir la suite du cours sur les curseurs. ▴
14
Langage PL/SQL Types de variables VARCHAR2 NUMBER(long,dec)
Longueur maximale : octets ; Exemples : name VARCHAR2(30); name VARCHAR2(30) := ’toto’ ; NUMBER(long,dec) Long : longueur maximale ; Dec : longueur de la partie décimale ; Exemples. Num_tel number(10); Salaire number(5,2)= ; ▴
15
Langage PL/SQL Types de variables (suite) DATE BOOLEAN
Fonction TO DATE ; Exemples : Start_date := to_date(’29-SEP-2003’,’DD-MON-YYYY’); La vraible sttart date est evaluée et analysée par oracle par 2 chiffre pour le jour, trois letters pour le mois et l’année sur 4 chirffrer separées par un tiret (-) start_date := to _date(’29-SEP-2003:13:01’,’DD-MON-YYYY:HH24:MI’) ; Ici La vraible start_date est evaluée et analysée par oracle par 2 chiffre pour le jour, trois letters pour le mois et l’année sur 4 chirffrer separées par un tiret (-). Avec aussi l’heurs et les minutes BOOLEAN TRUE FALSE NULL ▴
16
Langage PL/SQL Déclaration %TYPE et %ROWTYPE V_nom emp.nom.%TYPE;
On peut déclarer qu’une variable est du même type qu’une colonne d’une table ou (ou qu’une autre variable). V_employe emp%ROWTYPE; Une variable peut contenir toutes les colonnes d’un tuple d’une table (la variable v employe contiendra une ligne de la table emp). Important pour la robustesse du code ▴
17
Langage PL/SQL Déclaration %TYPE et %ROWTYPE -Exemple
DECLARE v_employe EMPLOYEES%ROWTYPE; v_nom EMPLOYEES.FIRST_NAME%TYPE; BEGIN SELECT * INTO v_employe FROM EMPLOYEES WHERE employee_id=100 ; v_nom :=v_employe.FIRST_NAME; v_employe.department_id:=20; v_employe.employee_id:=7777; u v_employe. ='changyah'; INSERT into employees VALUES v_employe; dbms_output.put_line ('ttt '|| v_employe.employee_id); END; Vérifier à bien retourner un seul tuple avec la reqête SELECT ...INTO ... ▴
18
Langage PL/SQL : Commandes
1 Les alternatives (if , else, elesif, case ) Les boucles (loop, while , for ) La commande GOTO Affichage (dbms_output.put_line () , chr(10)
19
Langage PL/SQL : Commandes
Test conditionnel IF-THEN IF v_date > ’01−JAN−08’ THEN V_salaire := V_salaire *1.15; END I F ; IF-THEN-ELSE IF v_date > ’01−JAN−08’ THEN V_salaire := v_salaire ∗ 1.15; ELSE V_salaire := v_salaire ∗ 1.05; END I F ; ▴
20
Langage PL/SQL : Commandes
Test conditionnel(2) IF-THEN-ELSIF IF v_nom =’PARKER’ THEN V_salaire:= V_salaire * 1.15; ELSIF v nom =’ SMITH ’ THEN V_salaire:= V_salaire *1.05 END I F ; ▴
21
Langage PL/SQL : Commandes
CASE CASE renvoie une valeur qui vaut resultat1 ou resultat2 ou ou resultat par défaut CASE selection WHEN expression1 THEN resultat1 WHEN expression2 THEN resultat2 ELSE resultat END ; . Exemple val:= CASE c i t y WHEN ’TORONTO’ THEN ’RAPTORS’ WHEN ’ LOS ANGELES ’ THEN ’ LAKERS ’ WHEN ’SAN ANTONIO ’ THEN ’ SPURS ’ \ ELSE ’NO TEAM’ END ; ▴
22
Langage PL/SQL : Commandes
CASE : Exemple DECLARE v_prix_vente NUMBER(9,2); v_Value NUMBER(9,2) := &v_prix_vente; v_taux_Commission NUMBER(3,2); BEGIN CASE WHEN v_Value <= 100 THEN v_taux_Commission := 0.03; WHEN v_Value <= 250 THEN v_taux_Commission := 0.05; WHEN v_Value <= 1000 THEN v_taux_Commission := 0.08; ELSE v_taux_Commission := 0.10; END CASE; DBMS_OUTPUT.PUT_LINE('Montant de la Commission est : ' || TO_CHAR(v_taux_Commission * v_Value) || 'Dirhames'); END;
23
Langage PL/SQL : Commandes
Les boucles : LOOP LOOP instructions ; EXIT [WHEN condition ] ; instructions ; END LOOP ; WHILE condition LOOP instructions ; END LOOP ; Exemple LOOP Monthly_value := daily_value*31 EXIT WHEN monthly_value > 4000; END LOOP ; Obligation d’utiliser la commande EXIT pour éviter une boucle infinie. ▴
24
Langage PL/SQL : Commandes
Les boucles : LOOP Exemple : Insérer 10 articles avec la date d’aujourd’hui. declare . . . V_Date DATE; V_compteur NUMBER( 2 ) := 1 ; BEGIN V_Date := SYSDATE; LOOP INSERT INTO article ( Artno , ADate ) VALUES ( v_compteur , v_Date ) ; V_compteur := V_compteur + 1 ; EXIT WHEN V_compteur > 1 0; END LOOP; END;/
25
Langage PL/SQL : Commandes
Les boucles : FOR FOR indice IN [ REVERSE ] debut . . fin LOOP instructions ; END LOOP ; Ne pas déclarer indice, il est d´eclaré implicitement. La variable de boucle prend successivement les valeurs de debut, debut + 1, debut + 2, . . ., jusqu’à la valeur fin. On pourra également utiliser un curseur dans la clause IN Le mot clef REVERSE à l’effet escompté. Exemple FOR ii IN REVERSE LOOP jj:=ii*31; END LOOP ▴
26
Langage PL/SQL : Commandes
GOTO PL/SQL contient aussi la commade GOTO qui permet de faire le branchement d’un programme d’un point un autre point durant sont execution, ça syntaxe est : GOTO <libelé>;
27
Langage PL/SQL : Commandes
GOTO DECLARE v_compteur NUMBER(2) := 1; BEGIN LOOP v_compteur := v_compteur + 1; IF v_compteur > 5 THEN GOTO stop_processing; END IF; DBMS_OUTPUT.PUT_LINE('v_compteur est : ' || v_compteur); END LOOP; <<stop_processing>> DBMS_OUTPUT.PUT_LINE(' la valeur finale de v_compteur final est ' || v_compteur ); END;
28
Langage PL/SQL : Commandes
Affichage Activer le retour écran : set serveroutput on size 10000 Sortie standard : dbms_output.put_line (chaıne); Concaténation de chaînes : opérateur || Exemple Si on veut un retour chariot on place le caractére suivant: chr(10) DECLARE i number (2); BEGIN FOR i IN LOOP dbms_output.put_line('Nombre: ‘|| i ); END LOOP; END ; / ’ Le caractère / seul sur une ligne déclenche l’évaluation. ▴
29
Langage PL/SQL : Commandes
Affichage Exemple bis DECLARE compteur number(3); i number(3); BEGIN SELECT COUNT( ∗ ) INTO compteur FROM Etudiant ; FOR i IN 1.. compteur LOOP dbms_output.put_line(‘Nombre : ‘|| i); END LOOP ; END ;
30
Gestion des Erreurs Section Exception Anomalie programmeur
Erreur Oracle
31
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 le traitement dans la partie Exception
32
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; Sortie du bloc après exécution du traitement
33
Gestion des Exceptions
Syntaxe : en cas de déclaration définition DECLARE nom_erreur EXCEPTION; BEGIN IF anomalie THEN RAISE nom_erreur ; EXCEPTION WHEN nom_erreur THEN traitement; END;
34
Gestion d’une erreur : exemple
DECLARE sal_nul EXCEPTION; sal employees.salary%TYPE; BEGIN SELECT MAX(salary) INTO sal FROM employees; IF sal > THEN RAISE sal_nul; Else dnms_output.put_line(‘vous pouvez augmenter le salaire de vos employés’); END IF; EXCEPTION WHEN sal_nul THEN dnms_output.put_line(‘plafond dépassé’) END;
35
Exceptions Prédéfinies
DUP_VAL_ON_INDEX Lorsqu’une instruction SQL tente de créer une valeur dupliquée dans une colonne sur laquelle un index unique a été défini INVALID_NUMBER Lorsqu’une instruction SQL spécifie un nombre invalide NO_DATA_FOUND Lorsqu’une instruction Select ne retourne aucune ligne TOO_MANY_ROWS Une instruction Select ne peut pas renvoyer plus d’une ligne sans provoquer l’exception TOO_MANY_ROWS VALUE_ERROR Provoquée dans des situations d’erreur résultant de valeurs tronquées ou converties ZERO_DIVIDE: au cas ou il y a une instruction qui effectue une division par Zéro
36
Exemple Aucune donnée retournée Procedure PL/SQL terminé avec succès.
Declare emp_Rec employees%ROWTYPE; Begin select * into emp_Rec from employees where employee_ID = 777; Exception when No_Data_Found then dbms_output.put_line(‘Aucune donnée retournée’); when other then null; End; / Aucune donnée retournée Procedure PL/SQL terminé avec succès.
37
Déclaration d’une Exception
Declare pas_comm EXCEPTION; salaire employees.salary%TYPE; commi employees.commition%TYPE; numero employees.employee_id%TYPE; Begin Select salary, commition, employee_id into salaire, commi, numero from employees where employee_id := &num_emp; If commi = 0 or commi is null then raise pas_comm else traitement … end if; Exception When pas_comm then dbms_output.put_line(‘ Pas de commission pour l’employé ID: ’|| numero); End; NB: num_emp fait référence à une variable extérieure au bloc PL/SQL)
38
Test d’exécution avec SQLCODE et SQLERRM
Fonction prédéfinie qui renvoie le statut d’erreur système de l’instruction qui vient d’être exécutée (si sans erreur, SQLCODE = 0). SQLERRM Fonction prédéfinie qui renvoie le message d’erreur associé à la valeur retournée par SQLCODE (si sans erreur, SQLERRM = ‘ORA-0000’). Exemple 1: Declare Begin dbms_output.enable; // equivalente à set serveroutput on dbms_output.put_line(‘SQLCODE: ‘ || to_char(SQLCODE)); dbms_output.put_line(‘SQLERRM: ‘ || SQLERRM); End; / SQLCODE: 0 SQLERRM: ORA-0000: exécution normale, terminé avec succès
39
Test d’exécution avec SQLCODE et SQLERRM
Exemple 2: Declare v number; Begin select salary into v from employees; dbms_output.enable; -- equivalente à set serveroutput on Exception when TOO_MANY_ROWS then dbms_output.put_line('SQLCODE:'|| to_char(SQLCODE)); dbms_output.put_line('SQLERRM:' || SQLERRM); End;
40
Test d’exécution avec SQLCODE et SQLERRM
Exemple 3: complet Declare pas_err EXCEPTION; v number; Begin select salary into v from employees where employee_id=100; if(SQLCODE=0) then raise pas_err; end if; Exception when TOO_MANY_ROWS then dbms_output.put_line('SQLCODE:'|| to_char(SQLCODE)); dbms_output.put_line('SQLERRM:' || SQLERRM); when NO_DATA_FOUND then WHEN pas_err THEN dbms_output.put_line('C''est corecte '); End;
41
Les curseur Définition Deux types de curseurs:
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:
42
Quatre Étapes de traitement d’un curseur explicite
Les curseurs explicites sont traitées en suivant un modèle en quatre étapes. Déclarer le CURSEUR: le curseur doit apparaitre dans la partie déclaration de bloc pl/sql Ouvrir le CURSEUR : par l’instruction OPEN, Parcourir les ligne du CURSEUR : par l’ instruction FETCH. Fermer le CURSEUR : une instruction close .
43
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 first_name , salary From employees where department_id= 10 order by salary; nom employees .first_name%TYPE; salaire employees . salary%TYPE; Begin … End;
44
Ouverture d’un curseur : Open
L’ouverture: 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 first_name , salary From employees where department_id= 10 order by salary; Begin …; open dept_10; End;
45
Traitement des lignes : Fetch
Les lignes ramenées sont traitées une par une, la valeur de chaque colonne doit être stockée dans une variable réceptrice Syntaxe: Fetch nom_curseur into liste_variables; Le Fetch ramène une ligne à la fois.
46
Exemple : Fetch Declare
cursor dept_10 is select first_name , salary From employees where department_id= 10 order by salary; nom employees .first_name%TYPE; salaire employees . salary%TYPE; Begin Open dept_10; Loop Fetch dept_10 into nom, salaire; If salaire > 2500 then insert into résultat values (nom,salaire); end if; exit when salaire = 5000; end loop; … End;
47
Fermeture : close Syntaxe: Close nom_curseur;
Action: libère la place de mémoire Declare cursor dept_10 is select first_name , salary From employees where department_id= 10 order by salary; nom employees .first_name%TYPE; salaire employees . salary%TYPE; Begin Open dept_10; Loop Fetch dept_10 into nom, salaire; If salaire > 2500 then insert into résultat values (nom,salaire); end if; exit when salaire = 5000; end loop; close dept_10; End;
48
Exemple : close Prompt ‘’Nombre de salaires ? ‘’ Accept nombre;
Declare Cursor c1 is select first_name, salary from employees order bay sal desc; vename employees. first_name %TYPE; vsal employees.salary%TYPE; Begin open c1; for i in 1..&nombre loop fetch c1 into vename, vsal; insert into resultat values (vsal, vename); end loop; close c1 End;
49
Les attributs d’un curseur
Définition indicateurs sur l’état d’un curseur. %FOUND : nom_curseur%FOUND TRUE: le dernier FETCH a ramené une ligne FALSE: plus de ligne %NOTFOUND: nom_curseur%NOTFOUND TRUE: le dénier FETCH n’a pas ramené de ligne %ISOPEN: nom_curseur%ISOPEN TRUE: le curseur est ouvert %ROWCOUNT: nom_curseur%rowcount Nbre de lignes ramenées par le Fetch
50
nom_curseur%Attribut
Utilisation des attribut du curseur Pour manipuler les attribut d’un curseur implicite on utilise SQL%Attribut Exemples : SQL%FOUND , SQL% ROWCOUNT Pour manipuler les attribut d’ un curseur explicite on utilise nom_curseur%Attribut Exemples : nom_curseur%FOUND , nom_curseur % ROWCOUNT)
51
Utilisation des attribut du curseur
Curseur Implicite : utilisation de l’attribut par SQL%Attribut CREATE TABLE temp_Employee9 AS SELECT * FROM Employees; DECLARE e_DeptNumber employees.Department_id%TYPE :=9; BEGIN DELETE FROM temp_Employee9 WHERE Department_id <> e_DeptNumber; IF SQL%FOUND THEN – Il y a des enregistrement supprimmée DBMS_OUTPUT.PUT_LINE('Nombre des enregistrement supprimés: ‘ || TO_CHAR(SQL%ROWCOUNT)); ELSE DBMS_OUTPUT.PUT_LINE('AUCUN enregistrement n''supprimés '); END IF; END;
52
Exemple - %FOUND Declare
cursor dept_10 is select first_name , salary From employees where department_id= 10 order by salary; nom employees .first_name%TYPE; salaire employees . salary%TYPE; Begin Open dept_10; Fetch dept_10 into nom, salaire; While dept_10%FOUND Loop If salaire > then insert into résultat values (nom,salaire); end if; end loop; close dept_10; End;
53
Exemple - %NOTFOUND Declare
cursor dept_10 is select first_name , salary From employees where department_id= 10 order by salary; nom employees .first_name%TYPE; salaire employees . salary%TYPE; Begin Open dept_10; Loop Fetch dept_10 into nom, salaire; Exit when dept_10%NOTFOUND; If salaire > then bdms_output.put_line( nom ||’ ,’ ||salaire); end if; end loop; close dept_10; End;
54
Exemple - %ISOPEN Declare
cursor dept_10 is select first_name , salary From employees where department_id= 10 order by salary; nom employees .first_name%TYPE; salaire employees . salary%TYPE; Begin If not(dept_10%ISOPEN) then Open dept_10; end if; Loop Fetch dept_10 into nom, salaire; Exit when dept_10%NOTFOUND; If salaire > 2500 then insert into résultat values (nom,salaire); end loop; close dept_10; End;
55
Exemple - %ROWCOUNT Declare
cursor dept_10 is select first_name , salary From employees where department_id= 10 order by salary; nom employees .first_name%TYPE; salaire employees . salary%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;
56
Boucle LOOP Exit when pour un curseur
Dans cette boucle on est obligé d’utiliser : Open LOOP FETCH CLOSE Exit when declare cursor c is select department_id, first_name from employees where department_id = 10; Name employees.first_name%type; Dept employees. department_id%type; Begin Open c; LOOP FETCH c into dept, name ; Exit when c%NOTFOUND ; dbms_output.put_line(name ); END LOOP; CLOSE c; end;
57
Boucle WHILE pour un curseur
declare cursor c is select department_id, first_name from employees where department_id = 10; Name employees.first_name%type; Dept employees.department_id%type; Begin Open c; FETCH c into dept, name ; while c%FOUND loop dbms_output.put_line(name); End loop; CLOSE c; end; Utiliser WHILE élimine le besoin de l’instruction EXIT WHEN en intégrant l'utilisation de l'attribut % FOUND. 2 instructions FETCH (Une juste avant le while et l’autre avant le END LOOP)
58
Boucle FOR pour un curseur
Elle simplifie la programmation car elle évite d’utiliser explicitement les instruction open, fetch, close, exit En plus elle déclare implicitement une variable de type « row » associée au curseur declare cursor c is select department_id, first_name from employees where department_id = 10; begin FOR emp IN c LOOP dbms_output.put_line(emp.first_name); END LOOP; end;
59
Mise à jour d’une table -La clause WHERE CURRENT OF
La clause WHERE CURRENT OF peut être utilisée pour exécuter des instructions DML sur la ligne actuelle du curseur. Cela facilite les mises à jour précises. Pour utiliser WHERE CURRENT OF, le curseur doit être créé avec une clause FOR UPDATE. On l’utilise avec UPDATE , DELETE
60
Exemples -La clause WHERE CURRENT OF
DECLARE CURSOR moncurseur IS SELECT Employee_ID FROM employees FOR UPDATE; e_Record moncurseur%ROWTYPE; BEGIN OPEN moncurseur; LOOP FETCH moncurseur INTO e_Record; EXIT WHEN moncurseur %NOTFOUND; IF e_Record.Employee_ID = '3334' THEN DELETE FROM Employees WHERE CURRENT OF moncurseur; END IF; END LOOP; CLOSE moncurseur; END; / DECLARE CURSOR moncurseur IS SELECT Employee_ID FROM employees FOR UPDATE; BEGIN FOR c_tmp IN moncurseur LOOP IF c_tmp.Employee_ID = ‘102' THEN UPDATE employees SET salary= salary + 350 WHERE CURRENT OF moncurseur; END IF; END LOOP; COMMIT; END;
61
Passer des paramètres à un curseur
Vous pouvez modifier les lignes de données renvoyées dans un jeu de résultats en généralisant code PL/SQL grâce à l'utilisation des paramètres. Les paramètres peuvent être utilisés pour spécifier les critères de sélection de la requête lorsque vous ouvrez le curseur. Déclarer curseurs entre parenthèses par nom et type de données, comme indiqué ici. Lorsque vous avez besoin de spécifier plusieurs parameter pour un curseurs, séparez les entrées par une virgule. La syntaxe est : CURSOR mycursor (param1 NUMBER, param2, type2 ...., paramn typen ) IS SELECT FROM tables WHERE (condition sur les parameters)
62
Passer des paramètres à un curseur
Exemple Declare CURSOR mycursor (param1 number, param2 number) is select Employee_ID , salary from employees where employee_id between param1 and param2; e_Record mycursor%rowtype; BEGIN OPEN mycursor('102','103'); FETCH mycursor INTO e_Record; loop DBMS_OUTPUT.PUT_LINE('Salare de ' || e_Record.Employee_ID || ': ' || e_Record.Salary ||' $'); exit when mycursor%notfound; end loop; CLOSE mycursor; /
63
Procédures et Fonctions stockées
Objectifs: Décrire les différentes utilisation des procédure et fonctions Créer des procédures et fonction stockées Appeler une procédure et une fonction Supprimer une procédure et une fonction
64
Procédures stockées GRANT CREATE PROCEDURE TO utilisateur_désiré;
Tout comme n’importe quel autre langage procédural, PL / SQL a des blocs de code qui sont appelées procédures. Vous pouvez appeler ces procédures par les autres blocs de code, ou directement à partir de SQL * Plus (ou par un autre programme client). Avant de créer des procédure il vous faut avoir les droits nécessaire GRANT CREATE PROCEDURE TO utilisateur_désiré;
65
Procédures stockées Un Simple exemple de procédure
CREATE PROCEDURE Bonjour IS BEGIN DBMS_OUTPUT.PUT_LINE(‘Bonjour Tout le monde ); END; Appel de la procédure Dans un autre bloc PL/SQL BEGIN Bonjour(); END; Par commande SQL*Plus exec Bonjour(); Ou bien Call Bonjour();
66
Procédures stockées Syntaxe générale CREATE OR REPLACE
PROCEDURE nom_procedure ( paramètres IN , OUT ) IS BEGIN Corps_de_la_procedure END; nom_procedure : est le nom de la procédure, il doit être significatif Corps_de_la_procedure: est une suite d’instruction PL/SQL qui définissent la suite logique de la procédure
67
Procédures stockées Paramètres
Les paramètres sont optionnels dans les procédure, dans l’exemple que nous avons déjà vu il n y a pas de paramètres CREATE OR REPLACE PROCEDURE HELLOWORLD IS BEGIN DBMS_OUTPUT.PUT_LINE(’Hello World!’); END; Où cas où il y a des paramètres on les introduit comme on le fait lors de la création de la table (nom_param type ) Exemple ( N int , titre varchar)
68
Procédures stockées 1 seul paramètre: Exemple
Nous allons écrire une simple procédure admettant un seul paramètre CREATE OR REPLACE PROCEDURE DISPN (N INT) IS BEGIN DBMS_OUTPUT.PUT_LINE(‘N est : ‘ || N); END; Cette procédure affiche la valeur de nombre N passé en paramètre SQL>call DISPN(555) N est : 555
69
Procédures stockées Plusieurs paramètres: Exemple CREATE OR REPLACE
PROCEDURE DISP_AB (A INT, B INT) IS BEGIN DBMS_OUTPUT.PUT_LINE(’A + B = ’ || (A + B)); DBMS_OUTPUT.PUT_LINE(’A * B = ’ || (A * B)); END; SQL> CALL DISP_AB(17,23); A + B = 40 A * B = 391
70
SQL> CALL DISP_NAME(’Billal Merssi’); Hi Billal Berssi !
Procédures stockées paramètres: Exemple avec une chaine de caractère CREATE OR REPLACE PROCEDURE DISP_NAME (NAME VARCHAR) IS BEGIN DBMS_OUTPUT.PUT_LINE(’Hi ’ || NAME || ’!’); END; SQL> CALL DISP_NAME(’Billal Merssi’); Hi Billal Berssi !
71
Procédures stockées Options : IN, OUT, IN OUT
Quand on fait par d’option les paramètres sont considérer comme IN par défaut IN : pour un paramètre en entrer il est généralement placé après l’affectation ( := ) OUT: pour un paramètre qui va recevoir des données dans le corps de la procédure il est généralement placé avant l’affectation ( := ) IN OUT: pour des paramètre qui sont à la fois des IN et des OUT
72
Procédures stockées Options : IN, OUT, IN OUT: exemple
CREATE OR REPLACE PROCEDURE SUM_AB (A INT, B INT, C OUT INT) IS BEGIN C := A + B; END; Faites appel à la procédure dans un bloc PL/SQL ! DECLARE R INT; BEGIN SUM_AB(23,29,R); DBMS_OUTPUT.PUT_LINE(’SUM IS: ’ || R); END;
73
Procédures stockées Exemple avec : IN OUT CREATE OR REPLACE
PROCEDURE DOUBLEN (N IN OUT INT) IS BEGIN N := N * 2; END; Faites appel à la procédure dans un bloc PL/SQL ! DECLARE R INT; BEGIN R := 7; DBMS_OUTPUT.PUT_LINE(’BEFORE CALL R IS: ’ || R); DOUBLEN(R); DBMS_OUTPUT.PUT_LINE(’AFTER CALL R IS: ’ || R); END;
74
Fonctions stockées Une fonction est un bloc PL/SQL nommé qui peut accepter des paramètres et être appelé. En règle générale, vous utilisez une fonction pour calculer une valeur Une fonction doit comporter une clause RETURN dans l'en-tête, et au moins une instruction RETURN dans la section exécutable. Les fonctions peuvent être stockées en tant qu'objets de schéma dans la base de données en vue d'exécutions répétées.
75
Fonctions stockées Syntaxe pour créer une fonction
CREATE [OR REPLACE] FUNCTION num_fonction [( param1 [mod1] datatype1, param2 [mod2] datatype 2, ….)] RETURN datatype IS|AS Block PL/SQL ;
76
Fonctions stockées Description des paramètres
77
Fonctions stockées get_salaty.sql
Exemple de création d’une fonction stockée get_salaty.sql create or replace function get_sal (p_id in employees.employee_id%type) return number is v_salary employees.salary%type:=0; begin select salary into v_salary from employees where employee_id=p_id; return v_salary; end ; /
78
Fonctions stockées Exemple suite
1- Créez le scripte pour définir la fonction get_salary. avec un paramètre IN pour renvoyer une valeur numérique. 2- Exécutez le script pour créer la fonction get_salary. 3- Appelez la fonction dans une expression PL/SQL, car elle renverra une valeur à l'environnement appelant. NB: - Une bonne pratique en matière de programmation consiste à affecter la valeur renvoyée à une variable et à utiliser une seule instruction RETURN dans la section exécutable du code. - La section de traitement des exceptions peut également contenir une instruction RETURN.
79
Fonctions stockées Exemple
-Créer une fonction tax qui sera appelée à partir d'une instruction SELECT. - La fonction accepte un paramètre NUMBER et renvoie la taxe après avoir multiplié la valeur du paramètre par 0,08. Create or replace function tax( p_value in number) Return number is Begin Return (p_value * 0.08); End tax; / Appelez la fonction TAX au sein d'une interrogation affichant: le code, le nom, le salaire et le prélèvement fiscal de l'employé. SELECT employee_id, tax(salary) FROM employees WHERE tax(salary)>(SELECT MAX(tax(salary)) FROM employees WHERE department_id = 30) ORDER BY tax(salary) DESC;
80
Fonctions stockées Exemple de restrictions relatives aux appels de fonctions depuis le code SQL CREATE OR REPLACE FUNCTION query_call_sql(a NUMBER) RETURN NUMBER IS s NUMBER; BEGIN SELECT salary INTO s FROM employees WHERE employee_id = 170; RETURN (s + a); END; / Lorsqu'elle est appelée depuis l'instruction UPDATE suivante, la fonction query_call_sql ci-dessus renvoie un message d’erreur UPDATE employees SET salary=query_call_sql(100) WHERE employee_id = 170;
81
Supprimer des fonctions et procédure
Fonctions stockées Supprimer des fonctions et procédure Lorsqu'une fonction stockée n'est plus nécessaire, vous pouvez la supprimer en utilisant une instruction SQL Pour supprimer une fonction stockée en exécutant la commande SQL DROP FUNCTION nom_fonction DROP PROCEDURE nom_procedure; La commande CREATE OR REPLACE est comparé à DROP puis CREATE
82
Procédures stockées CREATE OR REPLACE Que signifie CREATE OR REPLACE ?
Créer l’objet s’il n’existe pas s’il existe remplacer le corps de l’objets par ce nouveau corps Est-ce qu’on peut la remplacer par;? Supprimer l’objet Puis Créer l’objet NON question de droit et privilèges
83
PACKAGES DANS PL/SQL C’est quoi Un Package Création de Package Comment utiliser les package Avantage de Package
84
C’est quoi PACKAGES Package : est un ensemble des procédures , fonction, variable et instructions SQL qui sont rassemblés et stockés dans la base de données Une collection d'objets PL / SQL qui sont logiquement regroupés pour former une seule unité Ils peuvent contenir: Procédures, fonctions Curseurs, variables, des constantes tableaux Exceptions Typiquement, ils peuvent contenir règles et procedures pour traiter les commandes d'achat, par exemple.
85
La structure de Package
Applications Package Base données Variables globales et publique Spec BODY Variables locales et privées
86
La structure de Package
A deux parties: Spécification de package Déclare procédures publiques etc. D'autres programmes peuvent y accéder en dehors du package Corps package Body Met en œuvre les procédures, fonctions ect ..publiquement , mais peut également les spécifier comme privée Les unités privés ne sont accessibles que dans la portée de package lui-même Toutes les unités déclarées dans les spécifications doivent être mises en œuvre dans la partie Body
87
La structure de Package
Spécification de package Corps de package BODY [CREATE [OR REPLACE] PACKAGE BODY package_name {IS | AS} [collection_type_definition ...] [record_type_definition ...] [subtype_definition ...] [collection_declaration ...] [constant_declaration ...] [exception_declaration ...] [object_declaration ...] [record_declaration ...] [variable_declaration ...] [cursor_body ...] [function_spec ...] [procedure_spec ...] [BEGIN sequence_of_statements] END [package_name];] CREATE [OR REPLACE] PACKAGE package_name [AUTHID {IS | AS} [collection_type_definition ...] [record_type_definition ...] [subtype_definition ...] [collection_declaration ...] [constant_declaration ...] [exception_declaration ...] [object_declaration ...] [record_declaration ...] [variable_declaration ...] [cursor_spec ...] [function_spec ...] [procedure_spec ...] [call_spec ...] END [package_name];
88
La structure de Package
Exemple de déclaration de package CREATE OR REPLACE PACKAGE nom_ package IS PROCEDURE augm_sal(p1 NUMBER, p2 NUMBER); FUNCTION dep_bal (num_dept IN NUMBER) RETURN NUMBER; END nom_ package;
89
Exemple de déclaration de package (suite)
CREATE OR REPLACE PACKAGE BODY package_name IS PROCEDURE augm_sal (p1 NUMBER, p2 NUMBER) BEGIN update emplyees set salary=salary*1.1 where department_id=p2; END augm_sal; FUNCTION div_bal (num_dept IN IN NUMBER) RETURN NUMBER bal number; select sum(salary) into bal from emplyees where department_id= num_dept IN ; RETURN bal; END div_bal; END package_name;
90
L’intérêt de Package On vous a demandé de générer un nombre aléatoire entre 100 et 1000, Si ce nombre est paire insérer le dans la table tab_paire s’il est impaire insérer le dans la table tab_impaire Declare X number Begin -- générer un nombre aléatoire entre 100 et 1000 X:=dbms_random.value(100,1000) --code pour determiner si le nombre est paire ou non If (mode(x,2)=0) then ( x est paire) Else ( x est impaire) --code pour insertion If (x est paire) then insert into tab_paire Else insert into tab_impaire End if End; On peut vous poser aussi une autre question 67 est t’il paire ?
91
L’intérêt de Package Notre programme peut être décomposer en 3 parties
1-Générer une valeur aléatoire 2- Tester si cette valeur est paire ou non 3- Insérer la valeur dans la table adéquate On va donc représenter chaque partie comme étant une fonction ou procédure Rassembler toute ces partie dans un seul conteneur Ce conteneur est appelé PACKAGE
92
Package Spécifications BODY Create or replace package body XYZ is
Function num_aleatoire ( param1 number , param2 number ) return number Is V_alea number ; Begin V_alea:= round(dbms_random.value(param1, param2)); Return V_alea; End num_aleatoire ; Function c_paire ( Param number) return boolean begin If ( mod(Param,2)=0) then return TRUE; Else return FALSE; End if ; End c_paire ;… Create Or replace package XYZ is Function num_aleatoire ( param1 number , param2 number ) return number; Function c_paire ( Param number) return boolean ; Procedure insertion ( par1 number, par2 number ); End XYZ ;
93
Comment exécuter le package ?
BODY (suite) Procedure insertion ( par1 number, par2 number ) is num_ale number ; Begin num_ale := num_aleatoire(par1, par2); If (c_paire(Num_ale)) then insert into tab_paire values (num_ale); Else insert into tab_impaire values(num_ale); End if; Commit; End insertion ; End XYZ ; Comment exécuter le package ? Xyz.insertion( 200,700); Xyz. c_paire(67) Xyz. num_aleatoire(3 , 34);
94
Variables globales/ Variables locales
CREATE OR REPLACE PACKAGE pack1 IS V1 NUMBER:=1; Variable Globale Procedure proc1; End pack1; CREATE OR REPLACE PACKAGE BODY pack1 IS V2 NUMBER:=2; Variable Globale Procedure proc1 IS V3 NUMBER:=3; Variable locale BEGIN v1:=v1+1; v2:=v2+2; v3:=v3+3; DBMS_OUTPUT.PUT_LINE(‘v1 = ‘||v1); DBMS_OUTPUT.PUT_LINE(‘v2 = ‘||v2); DBMS_OUTPUT.PUT_LINE(‘v3 = ‘||v3); END proc1; END pack1;
95
Variables globales/ Variables locales
CREATE OR REPLACE PACKAGE pack1 IS V1 NUMBER:=1; Variable Globale Procedure proc1; End pack1; CREATE OR REPLACE PACKAGE BODY pack1 IS V2 NUMBER:=2; Variable Globale Procedure proc1 IS V3 NUMBER:=3; Variable locale BEGIN v1:=v1+1; v2:=v2+2; v3:=v3+3; DBMS_OUTPUT.PUT_LINE(‘v1 = ‘||v1); DBMS_OUTPUT.PUT_LINE(‘v2 = ‘||v2); DBMS_OUTPUT.PUT_LINE(‘v3 = ‘||v3); END proc1; END pack1; Execution 1er 2em 3 eme v1 2 3 4 v2 6 8 v3 Execute pack1.proc1 – faites le 3fois !
96
Pragma SERIALLY_REUSABLE
Provoque le / SQL PL exécution de jeter l'état d’écraser l’état de package . Donc instanciation se produit chaque fois qu'il est cité Pragma serially_reusable doit être appliqué à la fois à la spécification et le CORPS Maintenant, l'exécution de 3 fois le code précédent seraient les suivants Execution 1er 2em 3 eme CREATE OR REPLACE PACKAGE pack1 IS Pragma serially_reusable; V1 NUMBER:=1; Procedure proc1; End pack1; v1 2 v2 4 v3 6
97
Comment supprimer le package ?
Pour la suppression des specification et body DROP PACKAGE nom_package Pour la suppression de body seulement DROP PACKAGE BODY nom_package
98
Avantages de Package Les packages offrent plusieurs avantages:
La modularité, La conception plus facile d'application, Encapsulation des données et méthodes Ajout de fonctionnalités Meilleure performance.
99
Avantages de Package La modularité:
Les Package vous permettent d'encapsuler des types logiquement liés, des éléments et des sous-programmes dans un module PL / SQL nommée. Chaque package est facile à comprendre, et les interfaces entre les packages sont simples, clairs et bien définis. Ceci facilite le développement d'applications.
100
Avantages de Package La conception plus facile d'application:
Lors de la conception d'une application, Vous n’avez besoin initialement que de l'information sur d'interface des spécifications du package . Vous pouvez coder et compiler une spécification sans son corps (body). Puis, les sous-programmes référençant le package peuvent être compilées ainsi au fur et à mesure . Vous n’êtes pas obligés de définir tout les organes du package jusqu'à ce que vous êtes prêt à remplir tout l’application .
101
Avantages de Package Encapsulation des données et méthodes
Avec les packages, vous pouvez spécifier quels sont les types, les éléments et les sous-programmes publiques (visibles et accessibles) ou ceux privés (cachés et inaccessibles). Par exemple, si un package contient 4 sous-programmes, 3 public et 1 privé. Le package cache la mise en œuvre du sous-programme privé de sorte que seul le package (non votre l’application) est affecté en cas de changement de sa mise en œuvre. Cela simplifie la maintenance et l'amélioration. En outre.
102
Ajout de fonctionnalités
Avantages de Package Ajout de fonctionnalités Variables et curseurs publics packagée persistent durant la session. Ainsi, ils peuvent être partagés par tous les sous-programmes qui se exécutent dans l'environnement. En outre, ils vous permettent de maintenir des données à travers des transactions sans avoir recours à les stocker dans la base de données.
103
Meilleure performance.
Avantages de Package Meilleure performance. Lorsque vous appelez un sous-programme de package pour la première fois, l'ensemble du package est chargé en mémoire. Ainsi, les appels plus tard des autre sous-programmes de package ne nécessitent aucune E / S disque. En outre, les package stoppent les dépendances en cascade en évitant toute recompilation inutile. Par exemple, si vous changez la mise en œuvre d'une fonction du package , Oracle n'a pas besoin de recompiler touts les autres sous-programmes même ceux qui lui font appel, car ils sont ne indépendant sur le corps(body) du package .
104
Les Déclencheurs (Triggers) DANS PL/SQL
Définir un Déclencheur (Trigger) Décrire les différents types de triggers Décrire les triggers de la base de données et leurs utilisation Créer des triggers Décrire les régles de déclenchement des triggers Supprimer les triggers
105
Les Déclencheurs (Triggers) DANS PL/SQL
Définition : Un Trigger : Est un bloc ou d'une procédure PL / SQL associé à une table, une vue, un schéma ou à une donnée qui s’exécute implicitement(automatiquement) à chaque fois qu'un événement particulier a lieu. Type de Triggers Triggers d’application: est déclenché chaque fois qu'un événement se produit avec une application particulière Triggers base de données: est déclenché chaque fois qu'un événement de données (comme DML) ou un événement du système (telles que l'ouverture de session ou d'arrêt) se produit sur un schéma ou base de données
106
Les Déclencheurs (Triggers) DANS PL/SQL
Directives pour la conception Triggers Vous pouvez concevoir les Triggers pour : Effectuer des actions connexes Centraliser des opérations globales Vous ne devez pas concevoir Triggers Si : Leurs fonctionnalités est déjà intégrée dans le serveur Oracle ils dupliquent la même tache d'autres Triggers Vous pouvez créer des procédures stockées et les invoquer dans un Triggers, si le code PL / SQL est très longue. L'utilisation excessive de Triggers peut entraîner des interdépendances complexes, ce qui peut être difficile à maintenir dans de grandes applications
107
Les Déclencheurs (Triggers) DANS PL/SQL
CREATION de TRIGGER CREATE [OR REPLACE] TRIGGER nom_trigger Quand Evenement 1 [OR Evenement 2 OR Evenement3] ON nom_Objet [[REFERENCING OLD AS old | NEW AS new] FOR EACH ROW // pour chaque ligne [WHEN (condition)]] Begin Corps de trigger (PL/SQL bloc ) End;
108
Les Déclencheurs (Triggers) DANS PL/SQL
Les composantes de la syntaxe de creation de Triggers : nom_trigger : unique pour les trigger du meme schéma. Quant : indique quand le trigger va se déclancher en fonction avec l’evenement qui va se passer dans la BD : BEFORE, AFTER, et INSTEAD OF. Evenement : identifie l’opération DML qui provoque le declenchement INSERT, UPDATE [OF column], et DELETE. Nom_objet : indique la table ou la vue associés au trigger.
109
Les Déclencheurs (Triggers) DANS PL/SQL
Les composantes de la syntaxe de creation de Triggers (Suite) : Pour le trigger ligne vous pouvez specifier : REFERENCING : pour corréler les valeur old et new pour la ligne courante (par default OLD et NEW) FOR EACH ROW : pour indiquer que le trigger est une trigger ligne WHEN : clause pour appliquer un filtre, qui sera mis entre parentheses, Corps de trigger : C’est l’action à efectuer par le trigger, qui est implementé comme suit: Un bloc anonyme PL/SQL (DECLARE ou BEGIN, et un END) Appel à une procedure/fonction stoquée ou bien un package (CALL , EXECUTE)
110
Les Déclencheurs (Triggers) DANS PL/SQL
Types de Triggers DML Le type de trigger DML determine Si le Corps de trigger s’exécute pour chaque ligne ou une seule fois pour l’evenement déclanchant: Type 1: Les trigger de table (Trigger STATEMENT) : Excecutés une fois pour l’evenement déclanchante C’est le type par défaut des triggers Déclanchés meme s’il n y a aucune ligne affécté par l”evnement Type 2: Les Triggers ligne : Exécutés « séparément » pour chaque ligne affécté par l”evnement Ne sont pas executé Si l’evenement n’a affecté aucun ligne Sont indiqués en précisant la clause FOR EACH ROW
111
Les Déclencheurs (Triggers) DANS PL/SQL
Quand le trigger se déclence ? BEFORE: (Avant) Executer le trigger avant de proceder à l’evenement DML sur la table. AFTER (Aprés) Executer le trigger aprés l’evenement DML sur la table. INSTEAD OF: (au lieu de) Executer le corps de trigger au lieu de l’évenement. Ceci est utilisé pour les VUES qui ne sont pas modifiable Note: Si plusieurs Triggers sont définis pour un meme objet leurs déclancement est arbitraire
112
.… Les Déclencheurs (Triggers) DANS PL/SQL … … …
Séquence de déclenchement de Trigger Utilisez la séquence de déclenchement suivante pour un Trigger sur une table quand une seule ligne est manipulé: INSERT INTO departments (department_id,department_name, location_id) VALUES (400, 'CONSULTING', 2400); .… BEFORE avant le trigger tables BEFORE avant le trigger ligne … … … AFTER Aprés le trigger ligne AFTER Aprésle trigger tables
113
Les Déclencheurs (Triggers) DANS PL/SQL
UPDATE employees SET salary = salary * 1.1 WHERE department_id = 30; BEFORE avant le trigger tables BEFORE (avant) le trigger ligne AFTER (aprés) le trigger ligne …. BEFORE (avant) le trigger ligne AFTER (aprés) le trigger ligne AFTER (Aprés )le trigger tables
114
Les Déclencheurs (Triggers) DANS PL/SQL
Les types d’événement et le corps de triggers Événement de trigger : Determine quel Order DML va déclencher l’execution de trigger. Ils sont : INSERT UPDATE [OF column] DELETE Corps de triggers : Détermine l'action a effectuée Est-ce un bloc PL / SQL ou un appel à une procédure
115
Les Déclencheurs (Triggers) DANS PL/SQL
Création d’un trigger pour sécurisé l’insertion dans la table employees Application table EMPLOYEES INSERT INTO EMPLOYEES...; trigger SECURE_EMP CREATE OR REPLACE TRIGGER secure_emp BEFORE INSERT ON employees BEGIN IF (TO_CHAR(SYSDATE,'DY') IN ('DIM.','SAM.')) OR (TO_CHAR(SYSDATE,'HH24:MI') NOT BETWEEN '08:00' AND ‘18:00') then RAISE_APPLICATION_ERROR(-20500,'Vous ne pouvez inserer dans la table employes que durant les heures de travail'); END IF; END;
116
Les Déclencheurs (Triggers) DANS PL/SQL
Testons notre trigger INSERT INTO employees (employee_id, last_name, first_name, , hire_date, job_id, salary, department_id) VALUES (300, 'Smith', 'Rob', 'RSMITH', SYSDATE, ‘'IT_PROG', 4500, 60); Rapport d'erreur - Erreur SQL : ORA-20500: Vous ne pouvez inserer dans la table employes que durant les heures de travail ORA-06512: at "HR.SECURE_EMP", line 4 ORA-04088: error during execution of trigger 'HR.SECURE_EMP'
117
Les Déclencheurs (Triggers) DANS PL/SQL
Utilisation de prédicats conditionnels CREATE OR REPLACE TRIGGER secure_emp BEFORE INSERT OR UPDATE OR DELETE ON employees BEGIN IF (TO_CHAR(SYSDATE,'DY') IN ('SAM.','DIM.')) OR (TO_CHAR(SYSDATE,'HH24') NOT BETWEEN '08' AND '18') THEN IF DELETING THEN RAISE_APPLICATION_ERROR(-20502, 'Vous ne pouvezSupprimer dans la table employes que durant les heures de travail'); ELSIF INSERTING THEN RAISE_APPLICATION_ERROR(-20500, 'Vous ne pouvez inserer dans la table employes que durant les heures de travai.'); ELSIF UPDATING('SALARY') THEN RAISE_APPLICATION_ERROR(-20503, 'Vous ne pouvez changer dans la table employes que durant les heures de travai.'); ELSE RAISE_APPLICATION_ERROR(-20504, 'Vous ne pouvez changer dans la table employes que durant les heures Normales '); end if; END IF; END;
118
Les Déclencheurs (Triggers) DANS PL/SQL
Création d’un trigger ligne CREATE OR REPLACE TRIGGER Emp_count AFTER DELETE ON Emp_tab FOR EACH ROW DECLARE N INTEGER; BEGIN SELECT COUNT(*) INTO n FROM Emp_tab; DBMS_OUTPUT.PUT_LINE(‘il y a maintenant || n || 'employés') ; END ;
119
Les Déclencheurs (Triggers) DANS PL/SQL
Utilisation des qualificatifs : OLD et NEW Il ne sont utilisé que pour le trigger ligne lorsqu’un trigger ligne est mentionné à INSERT : Pas d’accès à l’élément OLD (qui n’existe pas) UPDATE : Accès possible à l’élément OLD et NEW DELETE : Pas d’accès à l’élément NEW (qui n’existe plus) CREATE OR REPLACE TRIGGER audit_emp_values AFTER DELETE OR INSERT OR UPDATE ON employees FOR EACH ROW BEGIN INSERT INTO audit_emp(user_name, time_stamp, id, old_last_name, new_last_name, old_title, new_title, old_salary, new_salary) VALUES (USER, SYSDATE, :OLD.employee_id, :OLD.last_name, :NEW.last_name, :OLD.job_id, :NEW.job_id, :OLD.salary, :NEW.salary); END;
120
Les Déclencheurs (Triggers) DANS PL/SQL
Restriction d'une Trigger ligne: Exemple CREATE OR REPLACE TRIGGER derive_commission_pct BEFORE INSERT OR UPDATE OF salary ON employees FOR EACH ROW WHEN (NEW.job_id = 'SA_REP') BEGIN IF INSERTING THEN :NEW.commission_pct := 0; ELSIF :OLD.commission_pct IS NULL THEN :NEW.commission_pct := 0; ELSE :NEW.commission_pct := :OLD.commission_pct+0.05; END IF; END; /
121
Les Déclencheurs (Triggers) DANS PL/SQL
Implémentation d’un trigger pour respecter une contrainte d’integrité UPDATE employees SET department_id = 999 WHERE employee_id = 102; -- Integrity constraint violation error CREATE OR REPLACE TRIGGER employee_dept_fk_trg AFTER UPDATE OF department_id ON employees FOR EACH ROW BEGIN INSERT INTO departments VALUES(:new.department_id, 'Dept '||:new.department_id, NULL, NULL); EXCEPTION WHEN DUP_VAL_ON_INDEX THEN NULL; -- masquer l’exception si le department existe déja END; UPDATE employees SET department_id = 999 WHERE employee_id = 102
122
Les Déclencheurs (Triggers) DANS PL/SQL
Le Trigger INSTEAD OF Application INSERT INTO ma_view . . .; INSERT TABLE1 Trigger de type INSTEAD OF UPDATE TABLE2 MA_VIEW
123
Les Déclencheurs (Triggers) DANS PL/SQL
Exemple de Le Trigger INSTEAD OF create view nom_emp as select employee_id,last_name,job_id from employees; insert into nom_emp values(7878,'LOLO','IT_PROG'); create or replace trigger ins_view_nom_emp instead of insert on nom_emp begin insert into employees values(:new.employee_id,null, :new.last_name, ' '||:new.last_name, null, sysdate, 'IT_PROG', null, null,null,null); end; insert into nom_emp values(7878,'LOLO','IT_PROG');
124
Procedures/Fonctions
Les Déclencheurs (Triggers) DANS PL/SQL Comparaison entre TRIGGERS et procédures/fonction stockées Triggers Définit par CREATE TRIGGER Le dictionnaire de données contient le code source dans USER_TRIGGERS. Implicitement invoqué Les COMMIT, SAVEPOINT, et ROLLBACK ne sont pas autorisés. Procedures/Fonctions Defined with CREATE PROCEDURE Le dictionnaire de données contient le code source dans USER_SOURCE. explicitement invoqué COMMIT, SAVEPOINT, et ROLLBACK sont autorisés
125
Les Déclencheurs (Triggers) DANS PL/SQL
Gestion des Triggers Activer ou désactiver un trigger: ALTER TRIGGER trigger_name DISABLE | ENABLE Activer ou désactiver tout les triggers d’une table: ALTER TABLE table_name DISABLE | ENABLE ALL TRIGGERS Recompiler un triggers d’une table : ALTER TRIGGER trigger_name COMPILE
126
Suppression des Triggers
Les Déclencheurs (Triggers) DANS PL/SQL Suppression des Triggers Pour supprimer un trigger de la base de données database, on utilise l’instruction DROP TRIGGER DROP TRIGGER trigger_name; Exemple DROP TRIGGER secure_emp; NB: Tout les triggers d’une table sont supprimés une fois table est supprimée.
Présentations similaires
© 2024 SlidePlayer.fr Inc.
All rights reserved.