P rocedural L anguage extensions to SQL Version 8.0 Disponible dans deux environnements: Les outils (Forms, Reports, Graphics) Au serveur de BD
Inclut les énoncés SQL. Langage avec une structure de bloc. Déclare des variables et des constantes. Affecte des valeurs aux variables. Opérateurs logiques. Fonctions built-in.
if - then if – then – else if – then - elsif loop - end loop for – end loop while – end loop exit goto null
On peut définir des zones de travail contenant plusieurs enregistrements (les curseurs) DECLARE CURSOR OPEN FETCH CLOSE
Une erreur ou un avertissement se nomme une exception Dans nos programmes nous pouvons mettre une : Section EXCEPTION EXCEPTION WHEN … THEN
Sous-programme Procédure externe Package Abstraction de données Collections Structures Types Déclarations et manipulation dobjets
3 sections Section déclarative (les variables) Section exécutable (le code) Section des exceptions La section exécutable est obligatoire Différentes sortes de blocs Anonyme, nommé, procédure ou fonction, déclencheur
DECLARE Section déclarative (les variables) BEGIN Section exécutable (le code) EXCEPTION Section des exceptions (si une erreur) END;
DECLARE V_NoEmp NUMBER(4) := 1010; V_NomE VARCHAR2(20); --variable BEGIN /* Retrouver les infos de l'élève */ SELECT NomE INTO V_NomE FROM Emp WHERE NoEmp = V_NoEmp; EXCEPTION WHEN NO_DATA_FOUND THEN INSERT INTO TableErreur (ColonneInfo) VALUES (Employé 1010 n''existe pas'); END;
-- sur une ligne * sur plusieurs lignes physiques *
Maximum 30 caractères tous significatifs Commence par une lettre Peut contenir $ _ # Pas d espace Pas de différence entre maj et min
Nombre 415, 21.6, 3.05 E19, null, … chaîne de caractères 31-jan-97 null booléen TRUE FALSE NULL
38 types différents Numérique NUMBER Caractère VARCHAR2, CHAR Booléen BOOLEAN Date Heure DATE
Nom_Var Type [CONSTANT] [NOT NULL] [:=valeur] Exemples : V_DateEmbauche DATE; V_AssezDonnees BOOLEAN; V_RevenueTot NUMBER (15,2); V_LongPara VARCHAR2(2000); C_Date CONSTANT DATE := 15-avr-99 ; V_Temp NUMBER NOT NULL := 0; V_Compte NUMBER := 0; V_Compte NUMBER DEFAULT 0; C_ValMin CONSTANT NUMBER(5) := 10; V_NoEmp Emp.NoEmp%TYPE; (Prend le type de la colonne NoEmp de la table Emp et lapplique à la variable V_NoEmp.
Op é rateurOp é ration **, NOT Puissance, N é gation +,-Signe *,/Mul, Div +, -Add, Sous || Concat é nation Op é rateurs Relationnels Voir ac é tate suivante ANDEt OROu
OpérateurOpération =Égal à <>, !=, ~=Différent <Plus petit >Plus grand <=Plus petit ou égal >=Plus grand ou égal
IS NULL Compare avec la valeur NULL IF V_Temp IS NULL THEN … LIKE Compare avec une valeur contenant des frimes V_Nom LIKE L%SE (permet Lise, Lyse ou Louise) BETWEEN IN
Seulement les énoncés de DML (Data Manipulation Language) SELECT INSERT UPDATE DELETE
INSERT en SQL INSERT INTO TABLE Classes (Dept, Cours, Groupe, Description, Max_Ele, Inscrits, Local) VALUES (INF,101, 2901, Intro prog,30, 28, C5:29); INSERT en PL/SQL DECLARE V_Texte Classes.Description%TYPE; BEGIN V_Texte := Intro prog; INSERT INTO Classes (Dept, Cours, Groupe, Description,Max_Ele, Inscrits, Local) VALUES (INF,101, 2901, V_Texte, 30, 28, C5:29); END;
Le SELECT doit retourner une ligne sinon il y aura erreur (EXCEPTION) SELECT Nom_Colonne INTO Variable FROM Table WHERE Clause_Where; Exemple: DECLARE V_Dept Classes.Dept%TYPE; V_Cours Classes.Cours%TYPE; BEGIN SELECT Dept, Cours INTO V_Dept, V_Cours FROM Classes WHERE Local = C5.29; END;
DECLARE V_No Eleve.No%TYPE; BEGIN SELECT Seq_EleveId.NEXTVAL INTO V_No FROM DUAL; INSERT INTO Eleve (No,Nom,Prenom) VALUES (V_No, Tard, Guy); INSERT INTO Eleve (No,Nom, Prenom) VALUES (Seq_EleveId.NEXTVAL, Polo, Marco); END;
Package permettant des sorties dans SQL*Plus venant de procédures PL/SQL Il faut obligatoirement avoir: SET SERVEROUTPUT ON PROCEDURE Prc_Sal (P_id NUMBER) IS V_TempSal NUMBER; BEGIN SELECT Salaire INTO V_TempSal FROM Employe WHERE id = P_id; DBMS_OUTPUT.PUT_LINE ('Salaire= || TO_CHAR(V_TempSal)); END;
IF condition THEN une séquence dinstructions END IF; Exemple: IF V_TotalVente > V_Quota THEN UPDATE Employe SET Salaire = Salaire + V_Bonus WHERE id = V_Temp; END IF;
IF condition THEN une séquence dinstructions ELSE une séquence dinstructions END IF; Exemple: IF V_TypeTrans = CR THEN UPDATE Compte SET Balance = Balance + V_Credit WHERE …; ELSE UPDATE Compte SET Balance = Balance – V_Credit WHERE …; END IF;
IF condition THEN une séquence dinstructions ELSIF condition THEN une séquence dinstructions ELSE une séquence dinstructions END IF; Exemple: IF V_TotalVentes > THEN V_Bonus:=15000; ELSIF V_TotalVentes > THEN V_Bonus:=5000; ELSE V_Bonus:=1000; END IF;
Quand une erreur arrive on dit quune exception sest produite Si nécessaire, on traite les exceptions dans la section EXCEPTION Il y a des exceptions: Pré-définies Définies par lusager
ACCESS_INTO_NULL DUP_VAL_ON_INDEX INVALID_NUMBER LOGIN_DENIED NO_DATA_FOUND NOT_LOGGED_ON TOO_MANY_ROWS VALUE_ERROR ZERO_DIVIDE OTHERS
DECLARE V_TempSal NUMBER; BEGIN SELECT salaire INTO V_TempSal FROM Employe WHERE Nom = Tremblay; … EXCEPTION WHEN NO_DATA_FOUND THEN Message(Tremblay nexiste pas); WHEN TOO_MANY_ROWS THEN Message(Il y a plusieurs Tremblay); END;
On utilise une exception usager lorsque lon rencontre un cas particulier (un cas à tous les 2 ans par exemple) Déclarations DECLARE Nom_Exeption EXCEPTION; … Déclenchement BEGIN IF Condition THEN RAISE Nom_Exception; … Code EXCEPTION WHEN Nom_Exception THEN Traitement de lexeption; END; …
Utiliser un éditeur pour écrire un énoncé SQL –CREATE PROCEDURE Transporter lénoncé dans SQLPLUS. Pour détruire la procédure –DROP PROCEDURE nom;
CREATE [OR REPLACE] PROCEDURE Nom_fct(Paramètres[,…]) IS [Déclarations] BEGIN Énoncés; [EXCEPTION Traitement d exception;] END;
Il est possible dutiliser les paramètres pour retourner de linformation (passage par valeur ou référence). Nom_Paramètre [ IN | OUT | INOUT ] Type [ := valeur par défaut ] pas de restriction sur le type Ex. NUMBER(4) - - invalide NUMBER - - valide IN : valeur transférée vers la procédure mais non retournée. OUT : valeur retournée uniquement. INOUT : valeur transféré et retournée. Par défaut le préfix IN est appliqué.
Exemple CREATE PROCEDURE Verif(P_Nom IN VARCHAR2, P_No OUT NUMBER) IS Déclaration BEGIN Énoncées; [EXEPTION Traitement des exceptions; END;]
Utiliser lénoncé SQL CREATE FUNCTION CREATE [OR REPLACE] FUNCTION Nom_fct(Paramètres[,…]) RETURN Type IS Déclarations BEGIN Enoncés; RETURN …; [EXCEPTION Traitement d exception;] END; Pour détruire la procédure –DROP FUNCTION Nom_fct;
Dune autre fonction ou procédure. Dun outils interactif ex: SQL PLUS. D une application Form builder programme avec pré-compilateur Dans un énoncé SQL (pour une fonction).
EXECUTE Nom_fct(Paramètre[,…¸]); Exemple: soit la procédure Fct_Augmt_Sal(P_NoEmp, P_Montant) EXECUTE Fct_Augmt_Sal (1043,200);
Créer une variable session VARIABLE V_Montant NUMBER Exécuter la fonction EXECUTE :V_Montant := Fct_Revenu(1243);
Dans SELECT, INSERT, UPDATE, DELETE, comme les fonctions SQL régulières SELECT Nom, TO_DATE(date_embauche), Revenu(id) FROM employe ORDER BY Revenu(id);
Met fin à lexécution d une procédure ou fonction. Fonction: RETURN (valeur) Procédure: RETURN
Les variables simples Les variables de type enregistrement Structure itérative (boucles) Définition et manipulation d'un curseur
Exemple 1: V_NoEmp employe.id%TYPE; (variable ayant le même type que la colonne id de la table employe) Exemple 2: V_Essai V_NoEmp%TYPE; (variable du même type qu'une autre variable)
LOOP Séquence d instructions END LOOP; on sort de la boucle avec: EXIT WHEN ou EXIT Exemple1: DECLARE … BEGIN LOOP SELECT… EXIT WHEN V_Salaire > 200; END LOOP; END;
Exemple2 On cherche le nom et le salaire du premier employé dont le salaire est plus grand que et on les inscrit dans la table Tempo. DECLARE V_SalEmploye.Salaire%TYPE; V_NomEEmploye.Nom%TYPE; BEGIN LOOP SELECT Nom, Salaire INTO V_Sal, V_NomE FROM Employe; IF V_Sal > THEN EXIT; END IF; END LOOP; INSERT INTO Tempo VALUES(V_Sal, V_NomE); COMMIT; END;
WHILE Condition LOOP Séquence d instructions LOOP; Exemple: On cherche le nom et le salaire du premier employé dont le salaire est supérieur à et on les inscrit dans la table tempo. DECLARE V_Sa;Employe.Salaire%TYPE; V_NomEEmploye.Nom%TYPE; BEGIN WHILE V_Sal < LOOP SELECT Salaire,Nom INTO V_Sal,V_ NomE FROM Employe; END LOOP; INSERT INTO Tempo VALUES(V_Sal, V_NomE); COMMIT; END;
FOR V_Compteur IN [REVERSE] BorneInf..BorneSup LOOP Séquence d'instructions; END LOOP; Bornes: variables ou des constantes numériques Si la variable compteur n'est pas définie à l'exécution de la boucle, elle le sera implicitement exemple: V_Limite := 50; FOR V_Compteur IN 1..V_Limite LOOP Séquences d'instructions; END LOOP; Note :lincrémentation ou la décrémentation ne peut être que de 1
L'utilisation d'un curseur nous permet de manipuler ligne par ligne le résultat d'une requête qui retourne plusieurs lignes. Le curseur pointe sur la ligne courante de l'ensemble des lignes. Mot clef CURSOR dans la section DECLARE d'un bloc d'instruction PL/SQL CURSOR NomDuCurseur IS Requete Exemple 1: CURSOR Cur_Vente IS SELECT Numero,Detail,Quantite FROM Produit;
CURSOR Cur_Vente IS SELECT Num, Detail, Qte FROM Jeu WHERE Qte > 30; Le curseur vente permet daccéder aux colonnes: Num, Detail et Qte de chacun des jeux dont la Qte > 30.
OPEN Nom_Curseur (initialisation (ouverture) du curseur) FETCH Nom_Curseur INTO Nom_Var [,…] (obtenir des informations de la ligne courrant et les placer dans les variables.) ex. FETCH Cur_Vente INTO V_Num, V_Detail,V_Qte CLOSE Nom_Curseur fermeture du curseur
Nom_Curseur%NOTFOUND: vrai, si la dernière instruction FETCH na pas réussie parce quil ne reste plus de rangée à traiter Nom_Curseur%FOUND: vrai si la dernière instruction FETCH a réussi Nom_Curseur%ROWCOUNT: retourne le nombre de rangées qui ont été traitées par linstruction FETCH Nom_Curseur%ISOPEN: donne vrai si le curseur est ouvert
Trouve le profit des jeux dont la cote est B et les résultats sont conservés dans une table (tempo) pour traitement ultérieur. DECLARE V_NoJeu.Numero%TYPE; V_PrixNetJeu.Detail%TYPE; V_PrixGrosJeu.Gros%TYPE; V_ProfitPourcentTempo.Profit%TYPE; CURSOR Cur_CurseurB IS SELECT Numero, Detail, Gros FROM Jeu WHERE Cote = B ; BEGIN OPEN Cur_CurseurB; curseur placé avant première rangée FETCH Cur_CurseurB INTO V_No, V_PrixNet, V_PrixGros; --cuseur placé sur la rangée suivante et met les infos dans --les variables WHILE Cur_CurseurB%FOUND LOOP V_ProfitPourcent := V_PrixNet – V_PrixGros/V_PrixNet * 100; INSERT INTO Tempo VALUES (V_No,V_ProfitPourcent); --traitement de la rangée suivante FETCH Cur_CurseurB INTO V_No, V_PrixNet, V_PrixGros; END LOOP; CLOSE Cur_CurseurB; COMMIT; END;
Exemple: DECLARE V_NoJeu.Numero%TYPE; V_PrixNetJeu.Detail%TYPE; V_PrixGrosJeu.Gros%TYPE; V_ProfitPourcentTempo.Profit%TYPE; CURSOR Cur_CurseurB IS SELECT Numero, Detail, Gros FROM Jeu WHERE Cote = B ; BEGIN OPEN Cur_CurseurB; curseur placé avant première rangée LOOP FETCH Cur_CurseurB INTO V_No, V_PrixNet, V_PrixGros; --cuseur placé sur la rangée suivante et met les infos dans --les variables EXIT WHEN Cur_CurseurB%NOTFOUND; --sort lorsqu il n y a plus de rangée à fetchée V_ProfitPourcent := V_PrixNet – V_PrixGros/V_PrixNet * 100; INSERT INTO Tempo VALUES (V_No,V_ProfitPourcent); END LOOP; CLOSE Cur_CurseurB; COMMIT; END;
Exemple: DECLARE V_NoJeu.Numero%TYPE; V_PrixNetJeu.Detail%TYPE; V_PrixGrosJeu.Gros%TYPE; V_ProfitPourcentTempo.Profit%TYPE; CURSOR Cur_CurseurB IS SELECT Numero, Detail, Gros FROM Jeu WHERE Cote = B ; --enregistrement pour recevoir les données fetchées Cur_LigneJeuCur_CurseurB%ROWTYPE; BEGIN --- OPEN curseur est fait implicitement FOR Cur_LigneJeu IN Cur_CurseurB LOOP ---un FETCH implicite est fait V_ProfitPourcent := Cur_LigneJeu.Detail – Cur_LigneJeu.Gros/ Cur_LigneJeu.Detail * 100; INSERT INTO Tempo VALUES (Cur_LigneJeu.Numero,V_ProfitPourcent); END LOOP; --- CLOSE curseur est fait implicitement COMMIT; END;