Vous êtes sur la page 1sur 17

mple >>] CASE oprateur { WHEN contenu_oprateur THEN { instruction;} ... }... [ELSE { instruction;}...

] END CASE [label]; recherche >>] CASE { WHEN expression_boolenne THEN { instruction;} ... }... [ELSE { instruction;}...] END CASE [label];

Cours 2me des Fetch suivants : 1er objets r peut tre n'importe quel type PL/SQL l'exception Fetch Fetch PLSQL
I- Le langage PLSQL

t Le langage de programmation PL a t introduit par la norme SQL2 qui a permis de ement rendre les bases de donnes actives. n (NESTED TABLE, INDEX-BY TABLE, VARRAY) Pour Oracle, ce langage est intitul PL SQL et existe depuis les premires versions dOracle. Il offre des structures de programmation classiques (itration, condition, branchement), ainsi que des fonctionnalits orientes base de donnes. Un bloc PLSQL est encadr par Begin et End. Les lignes se terminent pau un point virgule, alors que le bloc PLSQL se termine par un slash (/).
1)

Condition :

2)

Itration :

Case :

3) Les curseurs :

Un Curseur est un type de donnes correspondent un tableau issu dun Select dont le rsultat est stock en mmoire. Les curseurs sont manipuls travers trois tapes :
Open : Ouverture du curseur, Excution de la requte et stockage des rsultats en

mmoire. La dclaration du curseur ne provoque en aucun cas lexcution du select correspondant. Fetch : Navigation squentielle dans les lignes du curseur avec la rcupration dun enregistrement la fois Close : Fermeture du curseur et restitution des ressources systme initialement mobilises Curseur Employs Employee_id First_name 1 Adam 2 Blake Les curseurs sont soit implicites soit explicites. Ils sont explicites lorsquon crit dans le bloc de code qui les manipule les instructions Open, Fetch et Close. Ils sont implicites lorsque ces instructions ne sont pas indiques.
II- Les procdures

Les procdures sont des blocs PLSQL recevant des paramtres en entre et excutant des traitements. A la diffrence des fonctions, elles ne retournent aucun rsultat. Leur syntaxe est la suivante :

La dclaration des paramtres au sein de la procdure est effectue travers la syntaxe suivante :

Les paramtres passs la procdure sont de type : In : paramtre dentre avec passage par valeur Out : paramtre dentre avec passage par valeur. Paramtre utilis aussi pour le retour de valeurs In Out : paramtre dentre avec passage par adresse Procdure daffichage de la liste des 3 employs touchant le meilleur salaire travers un curseur explicite :

Create or replace procedure listemp IS Cursor CEmp is Select first_name,salary from employees order by salary desc; Vname employees.first_name%type; Vsal employees.salary%type; Begin Open CEmp; Fetch CEmp into vname,vsal; While CEmp%Found and CEmp%RowCount<=3 Loop DBMS_OUTPUT.PUT_LINE(vname || || vsal); Fetch CEmp into vname,vsal; End Loop; Close CEmp; End;
/

Procdure daffichage de la liste des 3 employs touchant le meilleur salaire travers un curseur implicite : Create or replace procedure listemp IS Cursor CEmp is Select first_name,salary from employees order by salary desc; C1 CEmp%Rowtype; i Number; Begin I := 1; For C1 in CEmp Loop DBMS_OUTPUT.PUT_LINE(C1.first_name || || C1.salary); I:= I + 1; If I>3 Then Exit; End If; End Loop; End; /
III- Les fonctions

Les fonctions sont des blocs PLSQL recevant en entre des paramtres et retournant un rsultat. Leur syntaxe est la suivante : Oooooopmm ;kjui)=

Lutilisation des paramtres est la mme que celle explicite pour les procdures.
IV- Les packages

Les packages sont des blocs de code PLSQL rassemblant des procdures, fonctions et constantes. Ils sont dclars en deux phases : Package specification o on dclare les en-ttes des procdures et fonctions, ainsi que les constantes Package Body o on dclare le corps des procdures et fonctions prciss dans le package specification Il est prciser que lordre de parution des procdures et fonctions dans le package body doit tre le mme que celui prcis dans le package specification. Les types et ordre des paramtres dentre ainsi que les types de retour doivent tre identiques entre procdures et fonctions. Toute divergence entraine une erreur de compilation. Prcisions ces lments travers un exemple simple :

Cration du package specification Create or replace package testpkg Is --Retourner le salaire maximal pour un department donn Function GetBestSal(vdept departments.department_id%type) Return Number;

--Augmenter le salaire des employs dun department donn dun pourcentage donn Procedure AddSal(vdept departments.department_id%type, pct Number); End;
/ Cration du package body Create or replace package body testpkg Is Function GetBestSal(vdept departments.department_id%type) Return Number IS Vsal employees.salary%type; Begin Select Max(Salary) into vsal from employees where department_id=vdept; Return vsal; End; Procedure AddSal(vdept departments.department_id%type, pct Number) IS Begin Update Employees Set Salary = Salary * (1+pct) Where department_id=vdept; Commit; End; End; Pour tester le package : Select testpkg.GetBestSal(10) from dual ;

Execute testpkg.AddSal(10,.2);
V- Les triggers

Les triggers sont des blocs PL SQL stocks dans la base de donnes dclenchs suite une commande LMD (insert, update ou delete). La squence dfinit le moment de lexcution du trigger i.e. avant, aprs ou au lieu de lordre LMD (before, after ou instead of). Le type de trigger, ligne ou commande, dfinit la frquence de son excution en corrlation avec le nombre de lignes traites par une instruction LMD. Pa exemple, un insert introduisant dan la base de donnes 100 lignes sera excut 1 fois pour un trigger commande (par exemple le trigger empchant le travail en dehors des horaires de travail) 100 fois pour un trigger ligne (for each row) La clause When, optionnelle, peut tre ajoute en dbut du trigger pour poser la condition qui permettra lexcution du trigger. Les pseudo colonnes :new et :old permettent de dsigner la valeur dune colonne rfrence dans un trigger. Elle dsignent respectivement la valeur aprs et avant lexcution de lordre LMD. Leur utilisation recquiert linstruction For Each Row et donc un trigger de type ligne. Illustrons lutilisation des triggers par quelques exemples Trigger dauto incrmentation de la cl primaire : Create table test (Code number(5), Nom varchar2(50)); Create sequence seq; Create or replace trigger setkey before insert on test For Each Row Begin Select seq.NextVal into :new.code From dual; End; / Pour tester le trigger : Insert into test (Nom) values (test); / Select * from test;

Trigger dinterdiction de travail sur la table employees le weekend : Create or replace trigger NoWork before insert or update or delete on employees Declare v number; Begin Select To_Char(sysdate,d) into v from dual; If v>=6 Then If Inserting Then Raise_Application_Error(-20300,Insertion interdite); End If; If Updating Then Raise_Application_Error(-20300,Modification interdite); End If; If Deleting Then Raise_Application_Error(-20300,Suppression interdite); End If; End If; End; / Trigger dinterdiction de rduction du salaire dun employ : Create or replace trigger NoDecrease Before update of salary on employees For Each Row Begin If :new.salary<:old.salary Then Raise_Application_Error(-20300 , Reduction Salaire Interdite); End If ; End ; Create table lcde (code number, Qte number(3), PU number(8,2), PT number(8,2)); Create or replace trigger trg05 before insert on lcde For each row Begin :new.pt := :new.qte*:new.pu; End; / Insert into lcde(code,qte,pu) values (1,8,9); Insert into lcde values (1,8,9,50); Select * from lcde;

Alter table employees add (department_name varchar2(30)); Create or replace trigger getdept before insert or update on employees For each row Begin Select department_name into :new.department_name From departments Where department_id = :new.department_id; End; / Update employees set department_id=40; Select * from employees; Rollback;

Exercices
Connect / as sysdba Select object_name from user_objects where object_type=PACKAGE
Connect hr/hr Crez les tables Create table Credit (num number(5), Datec date, Montant number(8,2), Nb_ech number(3), Interet number(2,2)); Alter table credit add constraint credit_pk primary key(num); Create table echeances (code_ech number(10), montantE number(8,2), DateE date, Num_credit number(5)); Alter table echeances add constraint ech_pk primary key (code_ech); Alter table echeances add constraint ech_cred_fk foreign key(num_credit) references credit(num);

Crer une procedure qui en fonction du credit (numrocredit,montant, taux dinteret, dure, datecrdit) insre des chances. Prvoir un trigger dincrmentation auto sur la table echeances.

Create sequence seq1 ; Create or replace trigger setkey before insert on echeances For each row Begin Select seq1.nextval into :new.code_ech from dual; End; / Create or replace procedure fill_ech(vcredit credit.num%type, vmontant credit.montant%type, vint credit.interet%type, vdur credit.nb_ech%type, vdate credit.datec%type) IS I number; Begin For I in 1..vdur Loop Insert into echeances (MontantE, dateE, num_credit) values ((vmontant*(1+vint))/vdur, Add_months(vdate,i),vcredit); End Loop; End; / Insert into credit values (1, 01/06/2011,10000, 12, .1); Execute fill_ech(1,10000,.1,10,01/06/2011); Select * from echeances;
-

Trigger sur la table crdit, qui ds quun crdit est insr, gnre ses chances

Create or replace trigger ech after insert on credit For each row Begin

Fill_ech(:new.num, :new.montant, :new.interet, :new.nb_ech, :new.datec); End; /

Alter table credit Add (typec char(1)); Create sequence seq4; Create or replace trigger trig01 before insert on credit For each row Begin Select Upper(:new.typec)|| to_char(sysdate,yyyy)||LPAD(seq4.nextval,5,0) into :new.num from dual; End; Drop table echeances cascade constraints; Delete from credit ; Commit ; Alter table credit modify (num varchar2(20));

Exo 1 1- Ajouter un champ nbemployees de type number(4) la table departments 2- Ecrire une requte qui renseigne ce champ 3- Ecrivez un trigger qui gre ce champ (+1 si ajout demploy, -1 si suppression demploy) Alter table departments add (nbemployees number(4)) ; Update departments d set nbemployees= (select count(*) from employees e Where e.department_id=d.department_id); Create or replace trigger setnbemp after insert or delete or update of department_id on employees For each row Begin If inserting then Update departments set nbemployees=nbemployees+1 where department_id=:new.department_id; End if; If deleting then Update departments set nbemployees=nbemployees-1 where department_id=:old.department_id; End if; If updating then Update departments set nbemployees=nbemployees-1 where department_id=:old.department_id; Update departments set nbemployees=nbemployees+1 where department_id=:new.department_id; End if; End;

/ Select * from departments; Update employees set department_id=10 where employee_id=202; Select * from departments; Exo2 1- Ecrivez un trigger de suppression en cascade partir de la table departments Create or replace trigger delcascade before delete on departments For each row Begin Delete employees where department_id=:old.department_id; End; / Exo3 Crer une table Create table auditE (code number(4) primary key, Emp number(4), Oldsal number(6,2), Newsal number(6,2), UserE varchar2(30), DateE date); Ecrivez le trigger qui permet dauditer les mises jour sur le champ salaire de la table employees Create sequence seq2;

Create or replace trigger seqA before insert on AuditE For each row Begin Select seq2.nextval into : new.code from dual; End; / Create or replace trigger Audi after update of salary on employees For each row Begin Insert into auditE (emp, oldsal, newsal, userE, dateE) values (:new.employee_id, :old.salary, :new.salary, User, Sysdate); End; / Alter table AuditE modify (oldsal number(8,2)) ; Alter table AuditE modify (newsal number(8,2)) ; Update employees set salary=salary*1.1 ; Select * from auditE; Exo4
1-

2-

3-

4-

Crez deux utilisateurs (user1 et user2) Connect / as sysdba Create user user1 identified by user1 ; Create user user2 identified by user2 ; Donnez leur les rles ncessaires Grant connect,resource to user1 ; Grant connect,resource to user2; Pour lutilisateur user1 Excutez le script summit2.sql Connect user1/user1 @c:\summit2.sql Crez un synonyme public pour la table s_ord Create public synonym s_ord for s_ord ; ERROR

Connect / as sysdba Grant create public synonym to user1; Connect user1/user1 Create public synonym s_ord for s_ord ;
56-

7-

8-

Donnez le droit daccs ce synomyme user2 Grant select on s_ord to user2 Testez le rsultat Connect user2/user2 Select * from s_ord; Ecrivez le trigger qui renseigne le champ total de la table s_ord la base des donnes de la table s_item Create or replace trigger calctotal after insert or update or delete on s_item For each row Begin Update s_ord set total= (Select sum(price*quantity) from s_item where ord_id=:new.ord_id) Where id=:new.ord_id; End; / Pour la gestion commandes partielement livres, crivez une procdure permettant le remplissage de la table Attenteliv dote des champs suivants : Champ Code Ord_id Product_id Reste_a_livrer DATEc Taille et type N(5) autoincrment N(7) N(7) N(9) date

Exo5 Connectez vous avec lutilisateur hr et crivez la procdure permettant de lister les dpartements et leurs employs sous la forme :

Dept1 Emp11 Emp12 Dept2 Emp21 Emp22 Emp23

Vous aimerez peut-être aussi