La présentation est en train de télécharger. S'il vous plaît, attendez

La présentation est en train de télécharger. S'il vous plaît, attendez

GIS882 Gestion des erreurs Packages ©Alain Villeneuve, 1999.

Présentations similaires


Présentation au sujet: "GIS882 Gestion des erreurs Packages ©Alain Villeneuve, 1999."— Transcription de la présentation:

1 GIS882 Gestion des erreurs Packages ©Alain Villeneuve, 1999

2 Erreurs dans Forms FORMS n Une erreur (exception) peut survenir dans: instruction SQL instruction PL/SQL un module PL/SQL appelé par un autre n Lorsqu'une erreur n'est pas gérée au niveau où elle survient, elle sera propagée au niveau supérieur n Le développeur peut manipuler lui-même l'exception et la rendre plus conviviale n Par défaut, à moins de gestion d'erreur, le reste du code est exécuté

3 Triggers dans Forms Triggers d'application dans FORMS n Oracle va essayer de récupérer le traitement suivant une erreur dans un trigger d'application n Le comportement par défaut est défini dans l'environnement FORMS (voir manuel de référence) n Exemples de triggers: –Pre-item –On-insert –When-validate-item –When-button-pressed –When-mouse-click n triggers au niveau du formulaire, du block, ou de l'item

4 Triggers Forms: stratégies Triggers d'application dans FORMS: 3 stratégies n écrire un gestionnaire complet d'exception n laisser le traitement par défaut à Oracle n ne gérer que les exceptions les plus critiques pour vous Fonctions disponibles n ERROR_TYPE(retourne CHAR) n ERROR_CODE(retourne NUMBER) n ERROR_TEXT(retourne CHAR) n DBMS_ERROR_CODE(retourne NUMBER) n DBMS_ERROR_TEXT(retourne CHAR)

5 Erreurs internes dans Forms Erreurs dans les routines internes (built-ins) n au delà d'une centaine de routines internes n exemples: GO_BLOCK ('nom_du_bloc'); GO_ITEM ('nom_item'); n FORM_SUCCESS (retourne un booléen) n FORM_FAILURE (retourne un booléen) n FORM_FATAL (retourne un booléen) n on signale l'erreur par RAISE FORM_TRIGGER_FAILURE dans le code; cette exception n'a pas à être définie dans votre code

6 Built-ins dans Forms Erreurs dans les routines internes (built-ins) Exemple: /* when_button_pressed trigger */ GO_BLOCK('bloc_quelconque'); IF NOT FORM_SUCCESS THEN RAISE Form_Trigger_Failure; END IF; END; Si le bloc désigné n'existe pas par exemple, alors le GO_BLOCK sera fautif et le FORM_SUCCESS sera à FALSE

7 n Chapitre Handling errors de Forms

8 PACKAGES n Sert à regrouper un ensemble d'objets, de types de données et de sous-programmes (fonctions et procédures) qui sont logiquement apparentés n consiste en deux grandes sections –la spécification du package –le corps du package n la spécification est l'interface visible du package –sert à déclarer les types, variables, constantes, exceptions, curseurs, et sous-programmes disponibles n le corps contient le code programmé en soi

9 Packages (2) n Un package est différent d'un programme normal contenant des sous-programmes n en essence, les deux types de construction se ressemblent mais le package a la particularité de permettre l'adressage à partir de l'externe des procédures qui le composent n une procédure qui contient des sous-programmes (d'autres procédures) ne permet pas d'atteindre directement ces sous-programmes de l'extérieur n le package au contraire permettra sous certaines conditions de rendre ses sous-programmes visibles

10 Exemple de package PACKAGE nom_package IS /* déclaration des variables, cursors, etc tous ces éléments sont publics et disponibles aux sous-programmes inclus dans le corps du package de plus ces déclarations sont visibles à l'environnement appelant */ END [nom_package]; PACKAGE BODY nom_package IS /* déclaration des variables, cursors, et autres objets privés codes programmés des sous-programmes */ BEGIN … -- instructions d'initialisation et autres END [nom_package]; Les sous- programmes viennent ici!

11 Avantages –programmation modulaire –facilité de développement –protection de l'implantation (information hiding) –fonctionnalités additionnelles à l'application –performance améliorée

12 Mise en place CREATE PACKAGE emp_actions AS /* Définition des types, cursors et exceptions visibles */ TYPE EmpRecTyp IS RECORD (emp_id INTEGER, salary REAL); TYPE DeptRecTyp IS RECORD (dept_id INTEGER, location VARCHAR2); CURSOR desc_salary RETURN EmpRecTyp; salary_missing EXCEPTION; Spécifications du package: déclaration des variables et objets. Suite de cette section sur la prochaine page.

13 Spécifications du package /* Sous-programmes visibles de l'extérieur. */ /* chacun peut être appelé par un autre programme */ FUNCTION hire_employee ( ename VARCHAR2, job VARCHAR2, mgr NUMBER, sal NUMBER, comm NUMBER, deptno NUMBER) RETURN INTEGER; PROCEDURE fire_employee (emp_id INTEGER); PROCEDURE raise_salary (emp_id INTEGER, increase NUMBER); FUNCTION nth_highest_salary (n INTEGER) RETURN EmpRecTyp; END emp_actions; Suite et fin de la partie spécifications du package. Tous ces éléments seront visibles. Fin des specs.

14 Corps du package PACKAGE BODY emp_actions IS number_hired INTEGER; -- variable visible au package seulement /* Définition du cursor déclaré dans la spécification du package. */ CURSOR desc_salary RETURN EmpRecTyp IS SELECT empno, sal FROM emp ORDER BY sal DESC; /* Chacun des sous-programmes sera défini en entier ici */ FUNCTION hire_employee (ename VARCHAR2, job VARCHAR2, mgr NUMBER, sal NUMBER, comm NUMBER, deptno NUMBER) RETURN INTEGER IS new_empno INTEGER; BEGIN Début du corps

15 Corps (2) SELECT empno_seq.NEXTVAL INTO new_empno FROM dual; INSERT INTO emp VALUES (new_empno, ename, job, mgr, SYSDATE, sal, comm, deptno); number_hired := number_hired + 1; RETURN new_empno; END hire_employee; Ceci marque la fin de la fonction hire_employee et non la fin du package: d'autres sous-programmes ont été déclarés qui doivent être définis avant le END final

16 Corps (3) PROCEDURE fire_employee (emp_id INTEGER) IS BEGIN DELETE FROM emp WHERE empno = emp_id; END fire_employee; Cette procédure sert à retirer un employé de la table emp.

17 Corps (4) PROCEDURE raise_salary (emp_id INTEGER, increase NUMBER) IS current_salary NUMBER; BEGIN SELECT sal INTO current_salary FROM emp WHERE empno = emp_id; IF current_salary IS NULL THEN RAISE salary_missing; ELSE UPDATE emp SET sal = sal + increase WHERE empno = emp_id; END IF; END raise_salary; Augmenter le salaire d'un employé par un certain montant

18 Corps (5) FUNCTION nth_highest_salary (n INTEGER) RETURN EmpRecTyp IS emp_rec EmpRecTyp; BEGIN OPEN desc_salary; FOR i IN 1..n LOOP FETCH desc_salary INTO emp_rec; END LOOP; CLOSE desc_salary; RETURN emp_rec; END nth_highest_salary; Retourne le record de l'employé qui a le nième salaire le plus élevé: le n (rang) désiré est fourni comme paramètre de la fonction. Sont définis dans le package specs.

19 Corps (6) /* Define local function, available only in package. */ FUNCTION rank (emp_id INTEGER, job_title VARCHAR2) RETURN INTEGER IS /* Return rank (highest = 1) of employee in a given job classification based on performance rating. */ head_count INTEGER; score NUMBER; BEGIN SELECT COUNT(*) INTO head_count FROM emp WHERE job = job_title; SELECT rating INTO score FROM reviews WHERE empno = emp_id; score := score / 100; -- maximum score is 100 RETURN (head_count + 1) - ROUND(head_count * score); END rank; Cette fonction est privée au package (donc pas visible à l'extérieur) parce qu'elle n'est pas annoncée dans le package specs

20 Corps (7) BEGIN -- initialization part starts here INSERT INTO emp_audit VALUES (SYSDATE, USER, 'EMP_ACTIONS'); number_hired := 0; END emp_actions; Entre le BEGIN et le END du corps du package, on placera les instructions d'initialisation requises par le package. Ici, on insère un tuplet dans un table de piste des événements pour fins de contrôle: c'est une idée farfelue puisque le BEGIN du package ne sera exécuté qu'une seule fois soit au premier appel.

21 Utilisation du package Appel ou référence à un composant d'un package: nom_package.nom_objet [paramètres optionnels] Exécution à partir de SQL*plus: EXECUTE nom_package.nom_fonction[paramètres] Exécution à partir de Reports, Forms via PL/SQL nom_package.nom_fonction[paramètres]

22 TABLEAUX PL/SQL n Structures de données en mémoire vive n ne comportent qu'une seule colonne n ne correspondent pas à une table SQL n les lignes de la table sont adressées par une valeur entière du type BINARY_INTEGER n taille dynamique: les tables s'agrandissent automatiquement au besoin n en fait, un tableau n'est ni plus ni moins qu'un vecteur n on pourra créer autant de tableaux PL/SQL qu'il y a de colonnes correspondantes dans la table désirée

23 Définition de tableau n Première étape: définir un type de référence DECLARE … TYPE type_tableau_nom IS TABLE OF CHAR(20) INDEX BY BINARY_INTEGER; n Deuxième étape: définir le tableau NOMS_EMPLOYESTYPE_TABLEAU_NOM; PRENOMS_EMPLOYESTYPE_TABLEAU_NOM; n Un tableau ne peut pas être initialisé dans sa déclaration n toujours mettre INDEX BY BINARY_INTEGER

24 Définition n Le %TYPE est aussi supporté dans la déclaration d'un tableau: DECLARE … TYPE type_tableau_nom IS TABLE OF employes.nom%TYPE INDEX BY BINARY_INTEGER; n Une variable BINARY_INTEGER est requise dans votre DECLARE pour adresser le tableau dans le programme iBINARY_INTEGER := 0; -- peut être initialisé n cette variable servira comme index dans le tableau

25 Utilisation n Limite de taille: –( à ) nombre de cellule –contraint à l'espace RAM réel n Utilisation des variables tableaux –comme toute autre variable simple –il faut toujours spécifier le numéro de cellule désiré, ceci se fait avec votre variable de type binary_integer n exemples nom_tableau(index) := valeur; IF nom_tableau(index) = … THEN

26 Exemple Exemple: Supposons un système de gestion des ressources humaines dans lequel plusieurs codes sont présents dans les dossiers d'employés (statut marital, sexe, statut d'emploi, etc.). Supposons aussi une table liste_codes qui contient les codes ainsi que leurs descriptions. Nous voulons imprimer les dossiers étoffés des employés. Plusieurs centaines d'employés existent dans la table.

27 Exemple (2) Alors typiquement, à chaque tuplet en provenance de la table employé, on devra aller chercher la description qui correspond à un code (statut marital), et ce pour chacun des codes. Cette recherche sera normalement par un SELECT. Supposons l'existence de 10 colonnes de code par employé et supposons 1000 employés dans la table, alors SELECT seront exécutés.

28 Exemple (3) Solution: n créer un package n le package aura une fonction de chargement de tous les codes dans un tableau PL/SQL n le package contiendra une fonction de recherche de la description d'un code et retournera celle-ci n le chargement initial serait dans la section BEGIN du package: nombre de SELECT totaux = 100 n n'oubliez pas que le package est initialisé lors du premier appel à n'importe laquelle de ses procédures

29 Exemple (4) Describe de la table codes codesnot nullvarchar2(8); descriptionnot nullvarchar2(30); Pour fins de cet exemple, on pose que tous les codes sont dans cette table de codes et que par exemple les deux premiers caractères de la clé identifie la catégorie de code: SX pour sexe, alors 'SXF', 'SXM' existent SM pour statut marital, alors 'SMC', 'SMM','SMV', … DD pour dernier diplôme, alors 'DDSEC5', 'DDDEC','DDBAA',...

30 Exemple (5) PACKAGE descriptifs IS TYPE description_codes IS TABLE OF codes.description%TYPE INDEX BY BINARY_INTEGER; TYPE code_code IS TABLE OF codes.code%TYPE INDEX BY BINARY_INTEGER; liste_codecode_code; --- tableau en soi liste_description description_codes; -- tableau en soi nombreNUMBER; -- compteur du nombre de codes FUNCTION retourne_descriptif(CODE codes.code%TYPE) RETURN CHAR; END descriptifs;

31 Exemple (6) PACKAGE BODY descriptifs IS CURSOR c_description IS SELECT * FROM codes; FUNCTION retourne_descriptif(CODE codes.code%TYPE) RETURN CHAR IS iBINARY_INTEGER := 0; BEGIN FOR i IN 1..nombre LOOP IF descriptifs.liste_code(i) = CODE THEN RETURN descriptifs.liste_description(i) END IF; END LOOP; RETURN ('Code invalide'); END retourne_descriptif; Lorsque l'on trouve la valeur recherchée, on retourne le descriptif qui lui correspond. Si fin de la boucle, c'est qu'on n'a rien trouvé!

32 Exemple (7) BEGIN -- ceci est le BEGIN du package et ne sera exécuté qu'une fois nombre := 1; OPEN c_description; LOOP FETCH c_description INTO liste_code(nombre), liste_description(nombre); EXIT WHEN c_description%NOTFOUND; nombre := nombre + 1; END LOOP; CLOSE c_description; END descriptifs; Les tableaux de codes et de descriptions sont chargés. Nombre contient le nombre réel d'entrées dans les tableaux.


Télécharger ppt "GIS882 Gestion des erreurs Packages ©Alain Villeneuve, 1999."

Présentations similaires


Annonces Google