GIS882 Gestion des erreurs Packages ©Alain Villeneuve, 1999.

32
GIS882 Gestion des erreurs Packages ©Alain Villeneuve, 1999

Transcript of GIS882 Gestion des erreurs Packages ©Alain Villeneuve, 1999.

Page 1: GIS882 Gestion des erreurs Packages ©Alain Villeneuve, 1999.

GIS882

Gestion des erreurs

Packages©Alain Villeneuve, 1999

Page 2: GIS882 Gestion des erreurs Packages ©Alain Villeneuve, 1999.

Erreurs dans Forms

FORMS Une erreur (exception) peut survenir dans:

instruction SQL

instruction PL/SQL

un module PL/SQL appelé par un autre

Lorsqu'une erreur n'est pas gérée au niveau où elle survient, elle sera propagée au niveau supérieur

Le développeur peut manipuler lui-même l'exception et la rendre plus conviviale

Par défaut, à moins de gestion d'erreur, le reste du code est exécuté

Page 3: GIS882 Gestion des erreurs Packages ©Alain Villeneuve, 1999.

Triggers dans FormsTriggers d'application dans FORMS Oracle va essayer de récupérer le traitement suivant

une erreur dans un trigger d'application Le comportement par défaut est défini dans

l'environnement FORMS (voir manuel de référence) Exemples de triggers:

– Pre-item– On-insert– When-validate-item– When-button-pressed– When-mouse-click

triggers au niveau du formulaire, du block, ou de l'item

Page 4: GIS882 Gestion des erreurs Packages ©Alain Villeneuve, 1999.

Triggers Forms: stratégies

Triggers d'application dans FORMS: 3 stratégies écrire un gestionnaire complet d'exception laisser le traitement par défaut à Oracle ne gérer que les exceptions les plus critiques pour vous

Fonctions disponibles ERROR_TYPE(retourne CHAR) ERROR_CODE(retourne NUMBER) ERROR_TEXT(retourne CHAR) DBMS_ERROR_CODE(retourne NUMBER) DBMS_ERROR_TEXT(retourne CHAR)

Page 5: GIS882 Gestion des erreurs Packages ©Alain Villeneuve, 1999.

Erreurs internes dans Forms

Erreurs dans les routines internes (built-ins) au delà d'une centaine de routines internes exemples:

GO_BLOCK ('nom_du_bloc');

GO_ITEM ('nom_item'); FORM_SUCCESS (retourne un booléen) FORM_FAILURE (retourne un booléen) FORM_FATAL (retourne un booléen) on signale l'erreur par RAISE FORM_TRIGGER_FAILURE

dans le code; cette exception n'a pas à être définie dans votre code

Page 6: GIS882 Gestion des erreurs Packages ©Alain Villeneuve, 1999.

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

Page 7: GIS882 Gestion des erreurs Packages ©Alain Villeneuve, 1999.

Chapitre Handling errors de Forms

Page 8: GIS882 Gestion des erreurs Packages ©Alain Villeneuve, 1999.

PACKAGES

Sert à regrouper un ensemble d'objets, de types de données et de sous-programmes (fonctions et procédures) qui sont logiquement apparentés

consiste en deux grandes sections– la spécification du package– le corps du package

la spécification est l'interface visible du package– sert à déclarer les types, variables, constantes, exceptions,

curseurs, et sous-programmes disponibles

le corps contient le code programmé en soi

Page 9: GIS882 Gestion des erreurs Packages ©Alain Villeneuve, 1999.

Packages (2)

Un package est différent d'un programme normal contenant des sous-programmes

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

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

le package au contraire permettra sous certaines conditions de rendre ses sous-programmes visibles

Page 10: GIS882 Gestion des erreurs Packages ©Alain Villeneuve, 1999.

Exemple de packagePACKAGE 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!

Page 11: GIS882 Gestion des erreurs Packages ©Alain Villeneuve, 1999.

Avantages

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

Page 12: GIS882 Gestion des erreurs Packages ©Alain Villeneuve, 1999.

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.

Page 13: GIS882 Gestion des erreurs Packages ©Alain Villeneuve, 1999.

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.

Page 14: GIS882 Gestion des erreurs Packages ©Alain Villeneuve, 1999.

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

Page 15: GIS882 Gestion des erreurs Packages ©Alain Villeneuve, 1999.

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

Page 16: GIS882 Gestion des erreurs Packages ©Alain Villeneuve, 1999.

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.

Page 17: GIS882 Gestion des erreurs Packages ©Alain Villeneuve, 1999.

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

Page 18: GIS882 Gestion des erreurs Packages ©Alain Villeneuve, 1999.

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.

Page 19: GIS882 Gestion des erreurs Packages ©Alain Villeneuve, 1999.

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

Page 20: GIS882 Gestion des erreurs Packages ©Alain Villeneuve, 1999.

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.

Page 21: GIS882 Gestion des erreurs Packages ©Alain Villeneuve, 1999.

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]

Page 22: GIS882 Gestion des erreurs Packages ©Alain Villeneuve, 1999.

TABLEAUX PL/SQL

Structures de données en mémoire vive ne comportent qu'une seule colonne ne correspondent pas à une table SQL les lignes de la table sont adressées par une valeur

entière du type BINARY_INTEGER taille dynamique: les tables s'agrandissent

automatiquement au besoin en fait, un tableau n'est ni plus ni moins qu'un vecteur on pourra créer autant de tableaux PL/SQL qu'il y a

de colonnes correspondantes dans la table désirée

Page 23: GIS882 Gestion des erreurs Packages ©Alain Villeneuve, 1999.

Définition de tableau

Première étape: définir un type de référenceDECLARE

TYPE type_tableau_nom IS TABLE OF CHAR(20) INDEX BY BINARY_INTEGER;

Deuxième étape: définir le tableauNOMS_EMPLOYES TYPE_TABLEAU_NOM;

PRENOMS_EMPLOYES TYPE_TABLEAU_NOM;

Un tableau ne peut pas être initialisé dans sa déclaration

toujours mettre INDEX BY BINARY_INTEGER

Page 24: GIS882 Gestion des erreurs Packages ©Alain Villeneuve, 1999.

Définition

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;

Une variable BINARY_INTEGER est requise dans votre DECLARE pour adresser le tableau dans le programmei BINARY_INTEGER := 0; -- peut être initialisé

cette variable servira comme index dans le tableau

Page 25: GIS882 Gestion des erreurs Packages ©Alain Villeneuve, 1999.

Utilisation

Limite de taille:– (-231 -1 à 231 - 1) nombre de cellule– contraint à l'espace RAM réel

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

exemplesnom_tableau(index) := valeur;

IF nom_tableau(index) = … THEN

Page 26: GIS882 Gestion des erreurs Packages ©Alain Villeneuve, 1999.

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.

Page 27: GIS882 Gestion des erreurs Packages ©Alain Villeneuve, 1999.

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 10.000 SELECT seront exécutés.

Page 28: GIS882 Gestion des erreurs Packages ©Alain Villeneuve, 1999.

Exemple (3)

Solution: créer un package le package aura une fonction de chargement de tous

les codes dans un tableau PL/SQL le package contiendra une fonction de recherche de

la description d'un code et retournera celle-ci le chargement initial serait dans la section BEGIN du

package: nombre de SELECT totaux = 100 n'oubliez pas que le package est initialisé lors du

premier appel à n'importe laquelle de ses procédures

Page 29: GIS882 Gestion des erreurs Packages ©Alain Villeneuve, 1999.

Exemple (4)

Describe de la table codescodes not null varchar2(8);

description not null varchar2(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',...

Page 30: GIS882 Gestion des erreurs Packages ©Alain Villeneuve, 1999.

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_code code_code; --- tableau en soi

liste_description description_codes; -- tableau en soi

nombre NUMBER; -- compteur du nombre de codes

FUNCTION retourne_descriptif(CODE codes.code%TYPE)

RETURN CHAR;

END descriptifs;

Page 31: GIS882 Gestion des erreurs Packages ©Alain Villeneuve, 1999.

Exemple (6)

PACKAGE BODY descriptifs ISCURSOR c_description IS SELECT * FROM codes;FUNCTION retourne_descriptif(CODE codes.code%TYPE)

RETURN CHAR ISi BINARY_INTEGER := 0;

BEGINFOR 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é!

Page 32: GIS882 Gestion des erreurs Packages ©Alain Villeneuve, 1999.

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.