Cours ORACLE Apprendre SQL avec Oracle SGBD le
Cours ORACLE
Apprendre SQL avec Oracle • SGBD le plus répandu dans le monde (gros, moyens et petits systèmes) • SGBD le plus normalisé • Produit téléchargeable sur oracle. com à des fins d’apprentissage • Interface SQL*Plus pour dialoguer avec le langage SQL 2
Oracle version libre • Offre d’un logiciel libre : Oracle XE • Disponible sur : www. oracle. com • Version 10 g et 11 g limitées • Disque : 2 gigas • Pas de limitation du nombre d’utilisateurs • Utilisation commerciale autorisée • Interface Windows conviviale 3
Le Langage de Bloc: PL/SQL: ‘Procédural Language’ • Chaque programme est un bloc (BEGIN – END) • Programmation adaptée pour : • Transactions • Une architecture Client - Serveur 4
Requêtes SQL • Chaque requête ‘client’ est transmise au serveur de données pour être exécutée avec retour de résultats CLIENT SERVEUR INSERT INTO … Exécute INSERT Résultat DELETE FROM … Exécute DELETE Résultat UPDATE … Exécute UPDATE Résultat Exécute SELECT Résultat SELECT … ……. 5
Bloc PL/SQL • Le bloc de requêtes est envoyé sur le serveur. Celui -ci exécute le bloc et renvoie 1 résultat final. CLIENT BEGIN INSERT … SERVEUR Exécution SI …. ALORS du bloc SELECT … PL/SQL FSI END; Résultat 6
Format d’un bloc PL/SQL • Section DECLARE : déclaration de • Variables locales simples • Variables tableaux • cursors • Section BEGIN • Section des ordres exécutables • Ordres SQL • Ordres PL • Section EXCEPTION • Réception en cas d’erreur • Exceptions SQL ou utilisateur DECLARE --déclarations BEGIN --exécutions EXCEPTION --erreurs END; 7
Variables simples • Variables de type SQL nbr NUMBER(2) ; nom VARCHAR(30) ; minimum CONSTANT INTEGER : = 5 ; salaire NUMBER(8, 2) ; debut NUMBER NOT NULL ; • Variables de type booléen (TRUE, FALSE, NULL) fin BOOLEAN ; reponse BOOLEAN DEFAULT TRUE ; ok BOOLEAN : = TRUE; 8
Variables faisant référence au dictionnaire de données • Référence à une colonne (table, vue) vsalaire vnom Vcomm employe. salaire%TYPE; etudiant. nom%TYPE; vsalaire%TYPE; • Référence à une ligne (table, vue) vemploye vetudiant employe%ROWTYPE; etudiant%ROWTYPE; 9
Variables paramétrées lues sous SQLPLUS : & • Variables lues par un ACCEPT …. PROMPT + PL + ACCEPT plu PROMPT 'Entrer la valeur : ' DECLARE -- déclarations BEGIN -- travail avec le contenu de plu : -- &plu si numérique -- '&plu' si caractère END; / -- Ordre SQL. . . 10
Variables en sortie sous SQLPLUS : : • Variable déclarée sous sqlplus , utilisée dans le bloc PL puis affichée sous sqlplus + PL + i NUMBER BEGIN i : = 15; DBMS_OUTPUT. PUT_LINE(i); END; / 11
Instructions PL • Affectation (: =) • A : = B; • Structure alternative ou conditionnelle • Opérateurs SQL : >, <, …. , OR, AND, …. , BETWEEN, LIKE, IN • IF …. THEN …. . ELSE ……END IF; IF condition THEN instructions; ELSE instructions; END IF; 12
Structure alternative : CASE (1) • Choix selon la valeur d’une variable CASE variable WHEN valeur 1 THEN action 1; WHEN valeur 2 THEN action 2; ……… ELSE action; END CASE; 13
Structure alternative : CASE (1)-Exemple. DECLARE v_grade CHAR(1) : = '&val'; BEGIN CASE v_grade WHEN 'A' THEN DBMS_OUTPUT. PUT_LINE('Grade A'); WHEN 'B' THEN DBMS_OUTPUT. PUT_LINE('Grade B'); WHEN 'C' THEN DBMS_OUTPUT. PUT_LINE('Grade C'); ELSE DBMS_OUTPUT. PUT_LINE('Grade n''existe pas'); END CASE; END; /
Structure alternative : CASE (2) • Plusieurs choix possibles CASE WHEN expression 1 THEN WHEN expression 2 THEN ……… ELSE action; action 1; action 2; END CASE; 15
Structure itérative • LOOP • FOR • WHILE LOOP instructions; EXIT WHEN (condition); END LOOP; FOR (indice IN [REVERSE] borne 1. . borne 2) LOOP instructions; END LOOP; WHILE (condition) LOOP instructions; END LOOP; 16
Structure itérative (Exemple: 1) DECLARE i NUMBER; BEGIN i: =1; LOOP DBMS_OUTPUT. PUT_LINE(i); i: =i+1; EXIT WHEN i > 5; END LOOP; END; /
Structure itérative (Exemple: 2) DECLARE i NUMBER(2); BEGIN FOR i IN 1. . 5 LOOP DBMS_OUTPUT. PUT_LINE('Nombre: ' || i); END LOOP; END; 18
Les procédures CREATE [OR REPLACE] PROCEDURE nom_procedure [(argument 1 datatype 1, argument 2 datatype 2)] IS | AS BEGIN -- INSTRUCTIONS END nom_procedure;
Les procédures - Exemple 1 CREATE PROCEDURE P 1 IS BEGIN DBMS_OUTPUT. PUT_LINE('Premiere procedure'); END; EXECUTE P 1; -- ou BEGIN P 1; END;
Les procédures - Exemple 2 CREATE OR REPLACE PROCEDURE P 2 IS v_count NUMBER; BEGIN SELECT count(*) INTO v_count FROM HR. EMPLOYEES WHERE DEPARTMENT_ID=30; DBMS_OUTPUT. PUT_LINE(v_count); END; exec P 2;
Les procédures - Exemple 3 CREATE OR REPLACE PROCEDURE P 3(v_id. Dep HR. EMPLOYEES. DEPARTMENT_ID%TYPE) IS v_count NUMBER; BEGIN SELECT count(*) INTO v_count FROM HR. EMPLOYEES WHERE DEPARTMENT_ID=v_id. Dep; DBMS_OUTPUT. PUT_LINE(v_count); END; EXEC P 3(&dep)
Les fonctions CREATE [OR REPLACE] FUNCTION nom_fonction [(argument 1 datatype 1, argument 2 datatype 2)] RETURN datatype IS | AS BEGIN -- INSTRUCTIONS RETURN valeur; END EXEC DBMS_OUTPUT. PUT_LINE(nom_fonction(…. ))
Les fonctions -Exemple 1 CREATE OR REPLACE FUNCTION F_Surface(rayon NUMBER) RETURN NUMBER IS pi CONSTANT NUMBER : = 3. 14; surf NUMBER; BEGIN surf : = pi*rayon; RETURN surf; END F_Surface; EXEC DBMS_OUTPUT. PUT_LINE(F_Surface(&r));
Les fonctions -Exemple 1 CREATE OR REPLACE FUNCTION Affich. Ecart(ID_Emp NUMBER) RETURN NUMBER IS v_Salmax NUMBER; v_sal NUMBER; v_ecrt NUMBER; BEGIN SELECT SALARY INTO v_sal FROM HR. EMPLOYEES WHERE EMPLOYEE_ID = ID_Emp; SELECT MAX(SALARY) INTO v_Salmax FROM HR. EMPLOYEES; v_ecrt: =v_Salmax-v_sal; RETURN v_ecrt; END Affich. Ecart; EXEC DBMS_OUTPUT. PUT_LINE(Affich. Ecart(&v));
Variables faisant référence à une ligne Syntaxe: Nom_variable Nom_Table%ROWTYPE Exemple: V_employe employe%ROWTYPE; V_etudiant etudiant%ROWTYPE;
CREATE OR REPLACE PROCEDURE Affiche. Info(Id_Emp NUMBER) IS v_emp HR. EMPLOYEES%ROWTYPE; BEGIN SELECT * INTO v_emp FROM HR. EMPLOYEES WHERE EMPLOYEE_ID = Id_Emp; DBMS_OUTPUT. PUT_LINE('Nom : '||v_emp. FIRST_NAME ||'| Date d’’entree : ' || v_emp. HIRE_DATE ||'| Salaire : ' || v_emp. SALARY || '|Departement : ' || v_emp. DEPARTMENT_ID); END Affiche. Info; EXEC Affiche. Info(&Id. Emp);
Tableaux dynamiques • Déclaration d’un type tableau TYPE <nom du type du tableau> IS TABLE OF <type de l’élément> INDEX BY PLS_INTEGER; • Affectation (héritage) de ce type à une variable <nom élément> <nom du type du tableau>; • Utilisation dans la section BEGIN : un élément du tableau : <nom élément>(rang dans le tableau) 28
Tableaux dynamiques variables simples • Déclaration d’un tableau avec des éléments numériques TYPE type_note_tab IS TABLE OF NUMBER(4, 2) INDEX BY PLS_INTEGER; tab_notes type_note_tab; tab_notes(1) : = 12. 5; Tab_notes(2) : = 14. 5; • Déclaration d’un tableau avec des éléments caractères TYPE type_nom_tab IS TABLE OF VARCHAR(30) i: =1; INDEX BY PLS_INTEGER; tab_noms(i): = ‘ISMAG'; tab_noms type_nom_tab; i NUMBER; 29
Exemple-1 DECLARE TYPE table 2 IS TABLE OF NUMBER INDEX BY PLS_INTEGER ; v_sal table 2; BEGIN v_sal(1): =100; v_sal(2): =200; v_sal(3): =300; DBMS_OUTPUT. PUT_LINE(v_sal(2)); END; /
Exemple-1 DECLARE TYPE table 2 IS TABLE OF NUMBER INDEX BY PLS_INTEGER ; v_sal table 2; BEGIN v_sal(1): =100; v_sal(2): =200; v_sal(3): =300; DBMS_OUTPUT. PUT_LINE(v_sal. count); DBMS_OUTPUT. PUT_LINE(v_sal. first)); DBMS_OUTPUT. PUT_LINE(v_sal. last)); END; /
Exemple-2 DECLARE TYPE tabl 1 IS TABLE OF NUMBER INDEX BY PLS_INTEGER; tab_notes tabl 1; i NUMBER: =1; BEGIN LOOP tab_notes(i): =i*2; DBMS_OUTPUT. PUT_LINE(tab_notes(i)); i: =i+1; EXIT WHEN(i>10); END LOOP; END;
Tableaux dynamiques avec référence à une colonne (table, vue) • Déclaration d’un tableau de type référence à une colonne (table, vue) TYPE type_note_tab IS TABLE OF Nom_tab. Nom_Champ%TYPE INDEX BY PLS_INTEGER; tab_notes type_note_tab; 33
Exemple-3 DECLARE TYPE Struct. Sal IS TABLE OF HR. EMPLOYEES. SALARY%TYPE INDEX BY PLS_INTEGER; v_sal Struct. Sal; BEGIN FOR i IN 101. . 110 LOOP SELECT SALARY INTO v_sal(i) FROM HR. EMPLOYEES WHERE EMPLOYEE_ID=i; DBMS_OUTPUT. PUT_LINE(i || '-----' || v_sal(i)); END LOOP; END; /
Tableaux dynamiques avec référence à une ligne (Enregistrement) TYPE tab 1 IS TABLE OF Nom_tab%ROWTYPE INDEX BY PLS_INTEGER; tab_notes tab 1; 35
Exemple-4 DECLARE TYPE Struct. Emp IS TABLE OF HR. EMPLOYEES%ROWTYPE INDEX BY PLS_INTEGER; v_emp Struct. Emp; BEGIN FOR i IN 101. . 110 LOOP SELECT FIRST_NAME, SALARY INTO v_emp(i). FIRST_NAME, v_emp(i). SALARY FROM HR. EMPLOYEES WHERE EMPLOYEE_ID=i; DBMS_OUTPUT. PUT_LINE(i ||'-------'||v_emp(i). FIRST_NAME || '-----' || v_emp(i). SALARY); END LOOP; END; /
Tableaux dynamiques avec des éléments de type RECORD • Type RECORD : plusieurs variables dans un élément TYPE type_emp_record IS RECORD (id. Emp NUMBER, nom. Emp VARCHAR(30), adr. Emp VARCHAR(80)); i: =1; tab_emps(i). id. Emp: = 100; tab_emps(i). nom. Emp: = ‘IDRISSI'; tab_emps(i). adr. Emp: = ‘Rue N° 12 Rabat'; TYPE type_emp_tab IS TABLE OF type_emp_record INDEX BY BINARY_INTEGER; tab_emps type_emp_tab; i NUMBER; 37
Sélection multi – ligne : les CURSEURS Principe des curseurs • Obligatoire pour sélectionner plusieurs lignes • Zone mémoire partagée pour stocker les résultats • Le curseur contient en permanence l’@ de la ligne courante 38
Démarche générale des curseurs • Déclaration du curseur : DECLARE • Ordre SQL sans exécution • Ouverture du curseur : OPEN • SQL ‘monte‘ les lignes sélectionnées en zone mémoire • Sélection d’une ligne : FETCH • Chaque FETCH ramène une ligne dans le programme client • Fermeture du curseur : CLOSE • Récupération de l’espace mémoire 39
Traitement d’un curseur Programme PL/SQL FETCH SGA variables DECLARE CURSOR c 1 IS SELECT ……; BEGIN OPEN c 1; LOOP FETCH c 1 INTO ………; EXIT WHEN c 1%NOTFOUND; ……… END LOOP; CLOSE c 1; END; OPEN BD 40
Les variables système des Curseurs • Curseur%FOUND • Variable booléenne • Curseur toujours ‘ouvert’ (encore des lignes) • Curseur%NOTFOUND • Curseur ‘fermé’ (plus de lignes) • Curseur%COUNT • Nombre de lignes déjà retournées • Curseur%ISOPEN • Booléen : curseur ouvert ? 41
Exemple-1 DECLARE CURSOR cr_emp IS SELECT FIRST_NAME FROM HR. EMPLOYEES v_name HR. EMPLOYEES. FIRST_NAME%TYPE; BEGIN OPEN cr_emp; LOOP FETCH cr_emp INTO v_name; EXIT WHEN cr_emp%NOTFOUND; DBMS_OUTPUT. PUT_LINE(v_name); END LOOP; CLOSE cr_emp; END;
Exemple-2 DECLARE CURSOR cr_emp IS SELECT FIRST_NAME FROM HR. EMPLOYEES v_name HR. EMPLOYEES. FIRST_NAME%TYPE; BEGIN FOR v_emp IN cr_emp LOOP EXIT WHEN cr_emp%NOTFOUND; DBMS_OUTPUT. PUT_LINE(v_emp. last_name || …………); END LOOP; END;
Exercice: Ecrire un curseur qui permet d’augmenter tous les salaires des employées par 1000
Exercice: DECLARE CURSOR Cr 1 IS SELECT * FROM emp; BEGIN FOR v_emp IN Cr 1 LOOP UPDATE emp SET salaire = salaire + 1000 WHERE nom = v_emp. nom; END LOOP; END;
Exemple -3 -(suite) DECLARE CURSOR Cr 1 IS SELECT * FROM emp FOR UPDATE; BEGIN FOR v_emp IN Cr 1 LOOP UPDATE emp SET salaire = salaire + 1000 WHERE CURRENT OF Cr 1; END LOOP; END;
Exercice: Ecrire un curseur qui permet de modifier les salaires des employées selon le département et la commission: - Si le département égal à 40 augmenter le salaire de 20% - Si le département égal à 70 augmenter le salaire de 15% - Si la commission est supérieure à 3 augmenter le salaire de 10% - Sinon augmenter le salaire de 5%
DECLARE CURSOR EMP_Cr IS SELECT EMPLOYEE_ID, DEPARTMENT_ID, COMMISSION_PCT FROM HR. EMPLOYEES; v_increment NUMBER; BEGIN FOR emp_rec IN EMP_Cr LOOP IF emp_rec. DEPARTMENT_ID = 40 THEN v_increment : = 1. 2; ELSIF emp_rec. DEPARTMENT_ID = 70 THEN v_increment : = 1. 15; ELSIF emp_rec. COMMISSION_PCT > 3 THEN v_increment : = 1. 1; ELSE v_increment : = 1. 05; END IF; UPDATE HR. EMPLOYEES SET SALARY = SALARY * v_increment WHERE DEPARTMENT_ID = emp_rec. DEPARTMENT_ID; END LOOP; END;
Exercice: CREATE TABLE Client ( Num. Cli integer primary key, Nom. Cli varchar(20), Adresse varchar(60) ); insert into Client values(1, 'Sté 1', 'Rue 1'); insert into Client values(2, 'Sté 2', 'Rue 2'); insert into Client values(3, 'Sté 3', 'Rue 3'); insert into Client values(4, 'Sté 4', 'Rue 4'); insert into Client values(6, 'Sté 6', 'Rue 6'); insert into Client values(8, 'Sté 8', 'Rue 8'); insert into Client values(10, 'Sté 10', 'Rue 10'); insert into Client values(14, 'Sté 14', 'Rue 14'); insert into Client values(15, 'Sté 15', 'Rue 15'); insert into Client values(18, 'Sté 18', 'Rue 18'); insert into Client values(21, 'Sté 21', 'Rue 21');
DECLARE CURSOR CR_Affich_id IS SELECT Num. Cli FROM Client; v_num integer; x integer; y integer; BEGIN OPEN CR_Affich_id; FETCH CR_Affich_id INTO v_num; WHILE CR_Affich_id%FOUND LOOP x: =v_num; DBMS_OUTPUT. PUT_LINE('id existe : '||x); FETCH CR_Affich_id INTO v_num; y: =v_num; WHILE y-x>1 LOOP DBMS_OUTPUT. PUT_LINE('id n''exsite pas : '||(x+1)); x: =x+1; END LOOP; CLOSE CR_Affich_id; END;
Les Triggers Syntaxe: CREATE [OR REPLACE] TRIGGER nom_trigger {BEFORE|AFTER} event_trigger ON nom_table [FORE EACH ROW [WHEN condition]] BEGIN Instructions. . . END nom_trigger;
Les Triggers Exemple 1: create table Client ( Id. Cli int primary key, Nom. Cli varchar(20), Age int );
Les Triggers Exemple 1: create table Client_log ( Utilisateur varchar(20), Operation varchar(20), Heure DATE ); CREATE OR REPLACE TRIGGER TRIG_INSC AFTER INSERT ON Client BEGIN INSERT INTO Client_log(Utilisateur, Operation, Heure) VALUES (USER, 'insert', SYSDATE); END;
Les Triggers Accès aux valeurs d’un trigger Exemple: : NEW id. Cmd Date. Cmd Qte. Prod 133 12/05/2018 5 Insert into commande values (133, ’ 12/05/2018’, 5); (1)
Les Triggers Accès aux valeurs d’un trigger Exemple: id. Cmd Date. Cmd Qte. Prod 133 12/05/2018 5 : NEW. Qte. Prod = 12 133 12/05/2018 12 133 Set Qte. Prod = 12 (2) Where id. Cmd = 133; : OLD. Qte. Prod = 5 : OLD Update commande 12/05/2018 5 Delete from commande Where id. Cmd = 133; (3)
Les Triggers Exemple: Commandes(id. Cmd, id. Prod, Qte. Cmd, cout_Unit, cout_Total, date_creation) create or replace trigger command_b_insert before insert on COMMANDES FOR EACH ROW BEGIN : new. cout_total : = : new. Qte. Cmd * : new. cout_unit; : new. date_creation : = sysdate; END; / Insert into COMMANDES(id. Cmd, id. Prod, Qte. Cmd, cout_Unit) values(1, 101, 15, 250);
Les Triggers Exercice 2. 1: INVENTAIRE(id. Pr , Qte_inv ) COMMANDES(id. Cmd, #id. Prod, Qte. Cmd, cout_Unit, cout_Total, date_creation)
Les Triggers Exercice 2. 1: CREATE OR REPLACE TRIGGER command_a_insert AFTER INSERT ON COMMANDES FOR EACH ROW BEGIN UPDATE INVENTAIRE SET Qte_inv = Qte_inv - : new. Qte. Cmd WHERE id. Pr = : new. id. Prod; END; /
Les Triggers Exercice 2. 2: Créer un triggers qui à la suppression d’une commande, le système n'accepte de supprimer que les commandes ayant la date moins de deux jours.
Les Triggers Exercice 2. 2: create or replace trigger Commandes_b_delete before delete on COMMANDES FOR EACH ROW DECLARE v_jour number; BEGIN select floor (sysdate - : old. date_creation) into v_jour from dual; if (v_jour > 2) then raise_application_error(-20007, 'Impossible de supprimer cette commande'); else update INVENTAIRE set Qte_inv = Qte_inv + : old. Qte. Cmd where id. Pr = : old. id. Prod; end if; END; /
Les Triggers Exercice 3: Créer les triggers suivants: -TR 1: Qui à l’ajout d’un employé, le trigger doit contrôler les salaires : ils doivent être plus grand que le plus petit des salaires et plus petit que le plus grand des salaire. - TR 2 : Qui à l’ajout d’un employé, le trigger permet d’ajouter « Id. Emp » d’une manière automatique.
Les Triggers Exercice 3: CREATE TABLE EMP 1 ( Id. Emp number, Nom varchar(16), Prenom varchar(20), salaire NUMBER ); INSERT INTO EMP 1 VALUES(1, 'idrissi', 'mohamed', 3000); INSERT INTO EMP 1 VALUES(2, 'mahmoudi', 'ali', 5000); INSERT INTO EMP 1 VALUES(3, 'badri', 'yassine', 7000); INSERT INTO EMP 1 VALUES(4, 'idrissi', 'sanae', 9000);
Les Triggers Exercice 3: TR 1 CREATE OR REPLACE TRIGGER CTRLsalaire BEFORE INSERT OR UPDATE ON EMP 1 FOR EACH ROW DECLARE minsal number; maxsal number; BEGIN SELECT MIN(salaire), Max(salaire) INTO minsal, maxsal FROM EMP 1; IF ( : new. salaire<minsal OR : new. salaire>maxsal) THEN raise_application_error (-20300, 'Salaire incorrect'); END IF; END;
Les Triggers Exercice 3: TR 2 CREATE OR REPLACE TRIGGER Incre. Id. Emp BEFORE INSERT OR UPDATE ON EMP 1 FOR EACH ROW DECLARE v_count number; BEGIN select count(*) into v_count from EMP 1; : new. Id. Emp : = v_count + 1; END;
Gestion ‘automatique’ des curseurs DECLARE CURSOR c 1 IS SELECT nom, moyenne FROM etudiant ORDER BY 1; -- PAS DE DECLARATION DE VARIABLE DE RECEPTION e 1 , e 2 NUMBER : =0; BEGIN --PAS D’OUVERTURE DE CURSEUR Variable STRUCT de réception --PAS DE FETCH FOR c 1_ligne IN c 1 LOOP IF c 1_ligne. moyenne < 10 THEN e 1: =e 1+1; INSERT INTO liste_refus VALUES(c 1_ligne. nom); ELSE e 2: =e 2+1; INSERT INTO liste_recus VALUES(c 1_ligne. nom); END IF; END LOOP; --PAS DE CLOSE DBMS_OUTPUT. PUT_LINE(TO_CHAR(e 2)||'Reçus '); DBMS_OUTPUT. PUT_LINE(TO_CHAR(e 1)||'Collés '); COMMIT; END; 65
Curseurs et Tableaux exemple final DECLARE CURSOR c 1 IS SELECT nom, moyenne FROM etudiant WHERE moyenne>=10 ORDER BY 2 DESC; TYPE type_nom_tab IS TABLE OF etudiant. nom%TYPE INDEX BY BINARY_INTEGER; tab_noms type_nom_tab; i, j NUMBER; BEGIN /* Remplissage tableau */ i: =1; FOR c 1_ligne IN c 1 LOOP tab_noms(i): = c 1_ligne. nom; i: =i+1; END LOOP; /* Affichage du tableau */ FOR j IN 1. . i-1 LOOP DBMS_OUTPUT. PUT_LINE('Rang : '||TO_CHAR(j)|| 'Etudiant : '||tab_nom(j)); END LOOP; END; 66
Gestion des Exceptions Principe • Toute erreur (SQL ou applicative) entraîne automatiquement un débranchement vers le paragraphe EXCEPTION : BEGIN Débranchement involontaire (erreur SQL) ou volontaire (erreur applicative) instruction 1; instruction 2; …… instructionn; EXCEPTION WHEN exception 1 THEN ……… WHEN exception 2 THEN ……… WHEN OTHERS THEN ……… END; 67
Deux types d’exceptions • Exceptions SQL • Déjà définies (pas de déclaration) • DUP_VAL_ON_INDEX • NO_DATA_FOUND • OTHERS • Non définies • Déclaration obligatoire avec le n° erreur (sqlcode) nomerreur EXCEPTION; PRAGMA EXCEPTION_INIT(nomerreur, n°erreur); • Exceptions applicatives • Déclaration sans n° erreur nomerreur EXCEPTION; 68
Exemple de gestion d’exception (1) DECLARE tropemprunt EXCEPTION; i NUMBER; BEGIN i: =1; SELECT …… i: =2; SELECT …… IF ……… THEN RAISE tropemprunt; ……… EXCEPTION WHEN NO_DATA_FOUND THEN IF i=1 THEN …… ELSE END IF; WHEN tropemprunt THEN ……… WHEN OTHERS THEN ……… END; 69
Exemple de gestion d’exception (2) DECLARE enfant_sans_parent EXCEPTION; PRAGMA EXCEPTION_INIT(enfant_sans_parent, -2291); BEGIN INSERT INTO fils VALUES ( ……. ); EXCEPTION WHEN enfant_sans_parent THEN ……… WHEN OTHERS THEN ……… END; 70
- Slides: 70