Télécharger la présentation
La présentation est en train de télécharger. S'il vous plaît, attendez
1
Révision du langage PL/SQL
2
Structure de bloc pour les blocs PL/SQL anonymes
DECLARE (facultatif) Déclarer les objets PL/SQL à utiliser dans ce bloc BEGIN (obligatoire) Définir les instructions exécutables EXCEPTION (facultatif) Définir les actions à entreprendre en cas d'erreur ou d'exception END; (obligatoire) Blocs anonymes Les blocs anonymes n'ont pas de nom. Vous les déclarez dans une application, à l'endroit où ils doivent être exécutés ; ils sont alors transmis au moteur PL/SQL pour exécution. La section comprise entre les mots-clés DECLARE et BEGIN se nomme la section déclarative. Vous y définissez les objets PL/SQL tels que les variables, constantes, curseurs et exceptions définies par l'utilisateur que vous voulez référencer dans le bloc. Le mot-clé DECLARE est facultatif si vous ne déclarez pas d'objet PL/SQL. Les mots-clés BEGIN et END sont obligatoires ; ils délimitent le corps des actions à réaliser. Ils constituent la section exécutable du bloc. La section comprise entre les mots-clés EXCEPTION et END se nomme la section de traitement des exceptions. Elle intercepte les conditions d'erreur. Vous y définissez les actions à entreprendre si la condition indiquée se réalise. La section de traitement des exceptions est facultative. Les mots-clés DECLARE, BEGIN et EXCEPTION ne sont pas suivis de points-virgules, contrairement à END et à toutes les autres instructions PL/SQL.
3
Déclarer des variables PL/SQL
Syntaxe : Exemples : identifier [CONSTANT] datatype [NOT NULL] [:= | DEFAULT expr]; Declare v_hiredate DATE; v_deptno NUMBER(2) NOT NULL := 10; v_location VARCHAR2(13) := 'Atlanta'; c_ comm CONSTANT NUMBER := 1400; v_count BINARY_INTEGER := 0; v_valid BOOLEAN NOT NULL := TRUE; Déclarer des variables PL/SQL Vous devez déclarer tous les identificateurs PL/SQL dans la section déclarative avant de les référencer dans le bloc PL/SQL. Vous avez la possibilité d'affecter une valeur initiale. Vous n'êtes pas obligé d'affecter une valeur à une variable pour la déclarer. Si vous référencez d'autres variables dans une déclaration, assurez-vous qu'elles ont été définies séparément dans une instruction antérieure. Dans la syntaxe, identifier correspond au nom de la variable. CONSTANT empêche toute modification de la valeur de la variable ; les constantes doivent être initialisées. datatype correspond à un type de données scalaire, composite, référencé ou LOB (ce cours ne traite que des types de données scalaires et composites). NOT NULL oblige la variable à posséder une valeur ; les variables NOT NULL doivent être initialisées. expr correspond à une expression PL/SQL pouvant représenter un littéral, une autre variable ou une expression mettant en jeu des opérateurs et des fonctions.
4
Déclarer des variables avec l'attribut %TYPE
Exemples : ... v_ename employees.last_name%TYPE; v_balance NUMBER(7,2); v_min_balance v_balance%TYPE := 10; Déclarer des variables avec l'attribut %TYPE Déclarez des variables pour stocker le nom d'un employé. ... v_ename employees.last_name%TYPE; Déclarez des variables pour stocker le solde d'un compte bancaire, ainsi que le solde minimum, lequel commence à 10. v_balance NUMBER(7,2); v_min_balance v_balance%TYPE := 10; Une contrainte de colonne NOT NULL ne s'applique pas aux variables déclarées avec %TYPE. Par conséquent, si vous déclarez une variable en utilisant l'attribut %TYPE et une colonne de base de données définie comme NOT NULL, vous pouvez affecter la valeur NULL à la variable.
5
Créer un enregistrement PL/SQL
Déclarer des variables pour le stockage du nom, du poste et du salaire d'un nouvel employé. Exemple : ... TYPE emp_record_type IS RECORD (ename VARCHAR2(25), job VARCHAR2(10), sal NUMBER(8,2)); emp_record emp_record_type; Créer un enregistrement PL/SQL Les déclarations de champ sont similaires aux déclarations de variable. Chaque champ possède un nom unique et un type de donnée précis. Il n'existe pas de types de données prédéfinis pour les enregistrements PL/SQL, comme c'est le cas pour les variables scalaires. Par conséquent, vous devez créer le type de données avant de déclarer un identificateur utilisant ce type. L'exemple suivant montre comment utiliser l'attribut %TYPE pour indiquer le type de données d'un champ : DECLARE TYPE emp_record_type IS RECORD (empid NUMBER(6) NOT NULL := 100, ename employees.last_name%TYPE, job employees.job_id%TYPE); emp_record emp_record_type; ... Remarque : Vous pouvez ajouter la contrainte NOT NULL à une déclaration de champ pour empêcher l'affectation de valeurs NULL au champ. N'oubliez pas d'initialiser les champs déclarés comme NOT NULL.
6
Attribut %ROWTYPE Exemples :
Déclarer une variable permettant de stocker les informations relatives à un service telles qu'elles figurent dans la table DEPARTMENTS. Déclarer une variable permettant de stocker les mêmes informations relatives à un employé telles qu'elles figurent dans la table EMPLOYEES. dept_record departments%ROWTYPE; Exemples La première déclaration de la diapositive crée un enregistrement comportant les mêmes noms et types de données de champ qu'une ligne de la table DEPARTMENTS. Les champs sont DEPARTMENT_ID, DEPARTMENT_NAME, MANAGER_ID et LOCATION_ID. La seconde déclaration ci-dessus crée un enregistrement comportant les mêmes noms et types de données de champ qu'une ligne de la table EMPLOYEES. Les champs sont EMPLOYEE_ID, FIRST_NAME, LAST_NAME, , PHONE_NUMBER, HIRE_DATE, JOB_ID, SALARY, COMMISSION_PCT, MANAGER_ID et DEPARTMENT_ID. Dans l'exemple suivant, vous sélectionnez les valeurs de colonne dans un enregistrement nommé item_record. DECLARE job_record jobs%ROWTYPE; ... BEGIN SELECT * INTO job_record FROM jobs WHERE ... emp_record employees%ROWTYPE;
7
Créer une table PL/SQL DECLARE TYPE ename_table_type IS TABLE OF
employees.last_name%TYPE INDEX BY BINARY_INTEGER; TYPE hiredate_table_type IS TABLE OF DATE ename_table ename_table_type; hiredate_table hiredate_table_type; BEGIN ename_table(1) := 'CAMERON'; hiredate_table(8) := SYSDATE + 7; IF ename_table.EXISTS(1) THEN INSERT INTO ... ... END; Créer une table PL/SQL Il n'existe pas de type de données prédéfini pour les enregistrements PL/SQL, comme c'est le cas pour les variables scalaires. Par conséquent, vous devez créer le type de données avant de déclarer un identificateur qui l'utilise. Référencer une table PL/SQL Syntaxe pl/sql_table_name(primary_key_value) où : primary_key_value est de type BINARY_INTEGER. Pour référencer la troisième ligne de la table PL/SQL ENAME_TABLE. ename_table(3) ... La plage de valeurs du type BINARY_INTEGER est comprise entre -2 147 483 647 et 2 147 483 647 ; par conséquent, la valeur de clé primaire peut être négative. L'indexation ne doit pas nécessairement commencer à 1. Remarque : L'instruction table.EXISTS(i) renvoie TRUE si au moins une ligne comportant l'index i est renvoyée. Utilisez l'instruction EXISTS pour éviter le déclenchement d'une erreur en cas de référence à un élément de table inexistant.
8
Instructions SELECT en PL/SQL
La clause INTO est obligatoire Exemple : DECLARE v_deptid NUMBER(4); v_loc NUMBER(4); BEGIN SELECT department_id, location_id INTO v_deptno, v_loc FROM departments WHERE department_name = 'Sales'; END; Clause INTO La clause INTO est obligatoire et apparaît entre les clauses SELECT et FROM. Elle permet de préciser les noms des variables contenant les valeurs renvoyées par SQL à partir de la clause SELECT. Vous devez indiquer une variable pour chaque élément sélectionné ; en outre, l'ordre des variables doit correspondre à celui des éléments sélectionnés. Vous devez utiliser la clause INTO pour remplir les variables PL/SQL ou les variables hôte. Les interrogations doivent renvoyer une et une seule ligne Les instructions SELECT d'un bloc PL/SQL se conforment à la norme ANSI du code SQL intégré, selon laquelle les interrogations doivent renvoyer une et une seule ligne. Une interrogation qui renvoie plusieurs lignes, ou qui n'en renvoie aucune, génère une erreur. Le langage PL/SQL gère ces erreurs en déclenchant des exceptions standard, que vous pouvez intercepter dans la section de traitement des exceptions du bloc avec les exceptions NO_DATA_FOUND et TOO_MANY_ROWS (le traitement des exceptions est abordé dans un chapitre ultérieur). Codez les instructions SELECT de manière à ne renvoyer qu'une seule ligne.
9
Insérer des données Ajouter les informations relatives à un nouvel
employé à la table EMPLOYEES Exemple : DECLARE v_empid employees.employee_id%TYPE; BEGIN SELECT employees_seq.NEXTVAL INTO v_empno FROM dual; INSERT INTO employees(employee_id, last_name, job_id, department_id) VALUES(v_empno, 'HARDING', 'PU_CLERK', 30); END; Insérer des données Utilisez des fonctions SQL, par exemple USER et SYSDATE. Générez des valeurs de clé primaire en utilisant des séquences de base de données. Dérivez des valeurs dans le bloc PL/SQL. Ajoutez des valeurs de colonne par défaut. Remarque : Il n'y a aucune ambiguïté possible entre les identificateurs et les noms de colonne dans l'instruction INSERT. Tout identificateur de la clause INSERT doit correspondre à un nom de colonne de base de données.
10
Mettre à jour les données
Augmenter le salaire de tous les employés chargés des achats dans la table EMPLOYEES. Exemple : DECLARE v_sal_increase employees.salary%TYPE := 2000; BEGIN UPDATE employees SET salary = salary + v_sal_increase WHERE job_id = 'PU_CLERK'; END; Mettre à jour et supprimer les données Il peut y avoir une ambiguïté dans la clause SET de l'instruction UPDATE ; en effet, bien que l'identificateur situé à gauche de l'opérateur d'affectation soit toujours une colonne de base de données, l'identificateur situé à droite peut correspondre à une colonne de base de données ou à une variable PL/SQL. Rappelons que la clause WHERE sert à déterminer les lignes qui seront affectées. En l'absence de modification de ligne, aucune erreur ne se produit, contrairement à l'instruction SELECT en PL/SQL. Remarque : Les affectations de variable PL/SQL se font toujours avec:=, tandis que les affectations de colonne SQL emploient toujours le signe =. N'oubliez pas que si les noms de colonne et les noms d'identificateur sont identiques dans la clause WHERE, le serveur Oracle commence par rechercher le nom dans la base de données.
11
Supprimer les données Supprimer les lignes appartenant au service 190 à partir de la table EMPLOYEES Exemple : DECLARE v_deptid employees.department_id%TYPE := 190; BEGIN DELETE FROM employees WHERE department_id = v_deptid; END; Supprimer les données Supprimez un poste particulier en procédant comme suit : DECLARE v_jobid jobs.job_id%TYPE := ‘PR_REP’; BEGIN DELETE FROM jobs WHERE job_id = v_jobid; END;
12
Instructions COMMIT et ROLLBACK
Initialiser une transaction avec la première instruction LMD suivant COMMIT ou ROLLBACK Utiliser les instructions SQL COMMIT et ROLLBACK pour mettre fin explicitement à une transaction Contrôler les transactions Contrôlez le déroulement des transactions en utilisant les instructions SQL COMMIT et ROLLBACK ; ainsi, vous pouvez rendre permanents ou abandonner des ensembles de modifications dans la base de données. De même qu'avec le serveur Oracle, les transactions LMD commencent à la première commande qui suit COMMIT ou ROLLBACK, et s'achèvent à la prochaine commande COMMIT ou ROLLBACK correctement exécutée. Les actions peuvent avoir lieu dans un bloc PL/SQL ou résulter d'événements liés à l'environnement hôte (par exemple, le fait de terminer une session iSQL*Plus entraîne la validation (commit) automatique de la transaction en cours). Instruction COMMIT COMMIT met fin à la transaction actuelle et rend permanentes les modifications en cours dans la base de données. Syntaxe COMMIT [WORK]; ROLLBACK [WORK]; où : WORK est conforme aux normes ANSI. Remarque : Les commandes de contrôle des transactions sont toutes valides en PL/SQL, bien que leur utilisation puisse être restreinte par l'environnement hôte. Vous pouvez également inclure des commandes de verrouillage explicite (par exemple LOCK TABLE et SELECT ... FOR UPDATE) dans un bloc (la commande FOR UPDATE est traitée de manière plus détaillée dans un chapitre ultérieur). Les commandes restent en vigueur jusqu'à la fin de la transaction. De même, un bloc PL/SQL n'implique pas nécessairement une transaction.
13
Attributs de curseur SQL
Grâce aux attributs d'un curseur SQL, vous pouvez tester le résultat lié à l'exécution d'instructions SQL SQL%ROWCOUNT Nombre de lignes affectées par la dernière instruction SQL (valeur entière) SQL%FOUND Attribut booléen qui prend la valeur TRUE si la dernière instruction SQL affecte une ou plusieurs lignes SQL%NOTFOUND Attribut booléen qui prend la valeur TRUE si la dernière instruction SQL n'affecte aucune ligne SQL%ISOPEN Prend toujours la valeur FALSE car PL/SQL ferme les curseurs implicites immédiatement après leur exécution Attributs de curseur SQL Les attributs de curseur SQL vous permettent de déterminer ce qui s'est passé lors de la dernière utilisation d'un curseur implicite. Ces attributs peuvent être utilisés dans les instructions PL/SQL (dans des fonctions par exemple) mais pas dans les instructions SQL. Vous pouvez utiliser les attributs SQL%ROWCOUNT, SQL%FOUND, SQL%NOTFOUND et SQL%ISOPEN dans la section de traitement des exceptions d'un bloc pour rassembler des informations sur l'exécution d'une instruction de manipulation de données. Le langage PL/SQL ne renvoie pas d'erreur si une instruction LMD n'affecte aucune ligne, contrairement à l'instruction SELECT, qui renvoie une exception.
14
Instructions IF-THEN-ELSIF
Pour une valeur entrée, renvoyer une valeur calculée Exemple : . . . IF v_start > 100 THEN v_start := 2 * v_start; ELSIF v_start >= 50 THEN v_start := 0.5 * v_start; ELSE v_start := 0.1 * v_start; END IF; Instructions IF-THEN-ELSIF Si possible, utilisez la clause ELSIF plutôt que des instructions IF imbriquées. Le code est plus facile à lire et à comprendre, et sa structure logique est plus claire. Si l'action associée à la commande ELSE consiste simplement en une autre instruction IF, il est préférable d'utiliser la clause ELSIF. Ceci rend le code plus clair grâce à la suppression des instructions END IF imbriquées nécessaires à la fin de chaque nouvel ensemble de conditions et d'actions. Exemple IF condition1 THEN statement1; ELSIF condition2 THEN statement2; ELSIF condition3 THEN statement3; END IF; L'exemple d'instructions IF-THEN-ELSIF de la diapositive a la signification suivante : Pour une valeur donnée entrée, renvoyer une valeur calculée. Si la valeur entrée est supérieure à 100, la valeur calculée vaut deux fois la valeur initiale. Si la valeur entrée est comprise entre 50 et 100, la valeur calculée vaut 50 % de la valeur initiale. Si la valeur entrée est inférieure à 50, la valeur calculée vaut 10 % de la valeur initiale. Remarque : Toute expression arithmétique contenant des valeurs NULL renvoie la valeur NULL.
15
Boucle de base Exemple : DECLARE
v_ordid order_items.order_id%TYPE := 101; v_counter NUMBER(2) := 1; BEGIN LOOP INSERT INTO order_items(order_id,line_item_id) VALUES(v_ordid, v_counter); v_counter := v_counter + 1; EXIT WHEN v_counter > 10; END LOOP; END; Boucle de base L'exemple de boucle de base présenté sur la diapositive a la signification suivante : insérer les 10 premiers nouveaux éléments de ligne pour le numéro de commande 101. Remarque : Une boucle simple permet d'exécuter les instructions associées au moins une fois, même si la condition est déjà vérifiée lors de l'entrée dans la boucle.
16
Boucle FOR Insérer les 10 premiers nouveaux éléments de ligne
pour le numéro de commande 101 Exemple : DECLARE v_ordid order_items.order_id%TYPE := 101; BEGIN FOR i IN LOOP INSERT INTO order_items(order_id,line_item_id) VALUES(v_ordid, i); END LOOP; END;
17
Boucle WHILE Exemple : ACCEPT p_price PROMPT 'Enter the price of the item: ' ACCEPT p_itemtot - PROMPT 'Enter the maximum total for purchase of item: ' DECLARE ... v_qty NUMBER(8) := 1; v_running_total NUMBER(7,2) := 0; BEGIN WHILE v_running_total < &p_itemtot LOOP v_qty := v_qty + 1; v_running_total := v_qty * &p_price; END LOOP; Boucle WHILE Dans l'exemple présenté sur la diapositive, la quantité d'éléments augmente à chaque itération de la boucle jusqu'à ce qu'elle atteigne le montant maximum de dépense autorisé.
18
Contrôler les curseurs explicites
Non DECLARE Créer une zone SQL nommée OPEN Charger la ligne en cours dans des variables FETCH CLOSE Oui VIDE ? Identifier l'ensemble actif Tester l'existence de lignes Libérer l'ensemble actif Si des lignes existent, revenir à FETCH Curseurs explicites Contrôler les curseurs explicites en utilisant quatre commandes 1. Déclarez le curseur en le nommant et en définissant la structure de l'interrogation à exécuter dans celui-ci. 2. Ouvrez le curseur. L'instruction OPEN exécute l'interrogation et affecte des valeurs à toutes les variables référencées. Les lignes identifiées par l'interrogation constituent l'ensemble actif et peuvent désormais être extraites. 3. Procédez à l'extraction des données à partir du curseur. L'instruction FETCH charge la ligne en cours à partir du curseur dans les variables. Chaque extraction oblige le curseur à déplacer son pointeur vers la ligne suivante de l'ensemble actif. Par conséquent, chaque extraction accède à une ligne différente renvoyée par l'interrogation. Dans l'organigramme présenté sur la diapositive, chaque extraction vérifie l'existence de lignes dans le curseur. Si des lignes existent, la ligne en cours est chargée dans les variables ; dans le cas contraire, le curseur est fermé. 4. Fermez le curseur. L'instruction CLOSE libère l'ensemble actif de lignes. Il est désormais possible de rouvrir le curseur pour établir un nouvel ensemble actif.
19
Déclarer le curseur Exemple : DECLARE CURSOR c1 IS
SELECT employee_id, last_name FROM employees; CURSOR c2 IS SELECT * FROM departments WHERE department_id = 10; BEGIN ... Déclaration de curseur explicite Extrayez les employés, un par un, en procédant comme suit : DECLARE v_empid employees.employee_id%TYPE; v_ename employees.last_name%TYPE; CURSOR c1 IS SELECT employee_id, last_name FROM employees; BEGIN ... Remarque : Vous pouvez référencer des variables dans l'interrogation, mais vous devez les déclarer avant l'instruction CURSOR.
20
Ouvrir le curseur Syntaxe :
Ouvrir le curseur pour exécuter l'interrogation et identifier l'ensemble actif Si l'interrogation ne renvoie pas de ligne, aucune exception n'est déclenchée Utiliser les attributs du curseur pour tester le résultat après une extraction OPEN cursor_name; Instruction OPEN Ouvrez le curseur pour exécuter l'interrogation et identifier l'ensemble de résultats ; ce dernier se compose de toutes les lignes répondant aux critères de recherche de l'interrogation. Le curseur pointe désormais vers la première ligne de l'ensemble de résultats. Dans la syntaxe, cursor_name correspond au nom du curseur déclaré précédemment. OPEN est une instruction exécutable qui accomplit les opérations suivantes : 1. Elle réalise des allocations dynamiques de mémoire pour une zone de contexte qui contient des informations de traitement cruciales. 2. Elle analyse l'instruction SELECT. 3. Elle affecte des valeurs aux les variables d'entrée ; en d'autres termes, elle fixe la valeur des variables d'entrée en obtenant leurs adresses mémoire. 4. Elle identifie l'ensemble de résultats, c'est-à-dire l'ensemble des lignes qui répondent aux critères de recherche. Les lignes de l'ensemble de résultats ne sont pas placées dans des variables lors de l'exécution de l'instruction OPEN. C'est l'instruction FETCH qui assure l'extraction des lignes. 5. Elle positionne le pointeur juste avant la première ligne dans l'ensemble actif. Remarque : Si l'interrogation ne renvoie aucune ligne lorsque le curseur est ouvert, le langage PL/SQL ne déclenche pas d'exception. Cependant, vous pouvez tester l'état du curseur après une extraction. Pour les curseurs déclarés avec la clause FOR UPDATE, l'instruction OPEN verrouille les lignes.
21
Extraire les données à partir du curseur
Exemples : FETCH c1 INTO v_empid, v_ename; ... OPEN defined_cursor; LOOP FETCH defined_cursor INTO defined_variables EXIT WHEN ...; -- Process the retrieved data END; Instruction FETCH (suite) L'instruction FETCH vous permet d'extraire les valeurs de la ligne en cours et de les placer dans des variables de sortie. Une fois l'extraction réalisée, vous pouvez manipuler les variables à l'aide d'autres instructions. Pour chaque valeur de colonne renvoyée par l'interrogation associée au curseur, une variable correspondante de type compatible doit exister dans la liste INTO. Extrayez les dix premiers employés, un par un. DECLARE v_empid employees.employee_id%TYPE; v_ename employees.last_name%TYPE; i NUMBER := 1; CURSOR c1 IS SELECT employee_id, last_name FROM employees; BEGIN OPEN c1; FOR i IN LOOP FETCH c1 INTO v_empid, v_ename; ... END LOOP; END ;
22
Fermer le curseur Syntaxe :
Fermer le curseur après avoir terminé le traitement des lignes Rouvrir le curseur, si nécessaire Ne pas essayer d'extraire les données d'un curseur s'il a été fermé CLOSE cursor_name; Instruction CLOSE L'instruction CLOSE désactive le curseur, et l'ensemble de résultats n'est plus défini. Fermez le curseur après avoir terminé le traitement de l'instruction SELECT. Ainsi, vous pouvez rouvrir le curseur, si nécessaire. Par conséquent, vous pouvez établir un ensemble actif à plusieurs reprises. Dans la syntaxe, cursor_name correspond au nom du curseur déclaré précédemment. N'essayez pas d'extraire des données à partir d'un curseur fermé, sinon l'exception INVALID_CURSOR se déclenchera. Remarque : L'instruction CLOSE libère la zone de contexte. Bien qu'il soit possible de sortir d'un bloc PL/SQL sans fermer les curseurs, vous devez prendre l'habitude de fermer tous les curseurs explicites déclarés, afin de libérer les ressources. Il existe une limite maximale au nombre de curseurs ouverts par utilisateur, qui est déterminée par le paramètre OPEN_CURSORS dans le fichier de paramètres de la base de données. OPEN_CURSORS = 50 par défaut. ... FOR i IN LOOP FETCH c1 INTO v_empid, v_ename; END LOOP; CLOSE c1; END;
23
Attributs d'un curseur explicite
Obtenir les informations d'état concernant un curseur Attribut Type Description %ISOPEN BOOLEAN Prend la valeur TRUE si le curseur est ouvert %NOTFOUND BOOLEAN Prend la valeur TRUE si la dernière extraction ne renvoie pas de ligne %FOUND BOOLEAN Prend la valeur TRUE si la dernière extraction renvoie une ligne ; complément de %NOTFOUND %ROWCOUNT NUMBER Prend la valeur correspondant au nombre total de lignes renvoyées jusqu'à présent Attributs d'un curseur explicite Comme pour les curseurs implicites, il existe quatre attributs permettant d'obtenir les informations d'état sur un curseur. Une fois joints au curseur ou à la variable de curseur, ces attributs renvoient des informations utiles sur l'exécution d'une instruction de manipulation de données. Remarque : Ne référencez pas des attributs de curseur directement dans une instruction SQL
24
Boucles FOR de curseur Procéder à l'extraction des employés, un par un, jusqu'au dernier Exemple : DECLARE CURSOR c1 IS SELECT employee_id, last_name FROM employees; BEGIN FOR emp_record IN c1 LOOP -- implicit open and implicit fetch occur IF emp_record.employee_id = 134 THEN ... END LOOP; -- implicit close occurs END; Boucles FOR de curseur Une boucle FOR de curseur traite les lignes dans un curseur explicite. Le curseur est ouvert, les lignes sont extraites une seule fois à chaque itération de la boucle. Le curseur se ferme ensuite automatiquement après que toutes les lignes ont été traitées. La boucle s'arrête d'elle-même à la fin de l'itération, après l'extraction de la dernière ligne.
25
Clause FOR UPDATE Procéder à l'extraction des commandes de plus de
1 000 $ traitées aujourd'hui Exemple : DECLARE CURSOR c1 IS SELECT customer_id, order_id FROM orders WHERE order_date = SYSDATE AND order_total > ORDER BY customer_id FOR UPDATE NOWAIT; Clause FOR UPDATE Si le Server Oracle8 ne peut pas obtenir le verrouillage des lignes demandées dans une instruction SELECT FOR UPDATE, il attend indéfiniment. Utilisez la clause NOWAIT dans l'instruction SELECT FOR UPDATE et examinez le code d'erreur renvoyé du fait qu'il est impossible d'obtenir le verrouillage dans une boucle. Vous pouvez ainsi réessayer d'ouvrir le curseur n fois avant de sortir du bloc PL/SQL. Si vous avez l'intention de mettre à jour ou de supprimer des lignes en utilisant la clause WHERE CURRENT OF, vous devez indiquer un nom de colonne dans la clause FOR UPDATE OF. Si votre table est volumineuse, vous obtiendrez de meilleures performances en utilisant l'instruction LOCK TABLE pour verrouiller l'ensemble des lignes de la table. Cependant, si vous utilisez LOCK TABLE, vous ne pourrez pas utiliser la clause WHERE CURRENT OF et devrez recourir à la notation WHERE column = identifier.
26
Clause WHERE CURRENT OF
Exemple : DECLARE CURSOR c1 IS SELECT salary FROM employees FOR UPDATE OF salary NOWAIT; BEGIN ... FOR emp_record IN c1 LOOP UPDATE ... WHERE CURRENT OF c1; END LOOP; COMMIT; END; Clause WHERE CURRENT OF Vous pouvez mettre à jour des lignes à partir des critères d'un curseur. De plus, vous pouvez écrire une instruction DELETE ou UPDATE contenant la clause WHERE CURRENT OF cursor_name pour faire référence à la dernière ligne traitée par l'instruction FETCH. Lorsque vous utilisez cette clause, le curseur référencé doit exister et contenir la clause FOR UPDATE dans son interrogation ; dans le cas contraire, vous recevrez une erreur. La clause vous permet de mettre à jour ou de supprimer la ligne en cours sans devoir référencer explicitement la pseudo-colonne ROWID.
27
Intercepter les erreurs prédéfinies du serveur Oracle
Utiliser le nom standard à l'intérieur du sous-programme de traitement des exceptions Exemples d'exceptions prédéfinies : NO_DATA_FOUND TOO_MANY_ROWS INVALID_CURSOR ZERO_DIVIDE DUP_VAL_ON_INDEX Intercepter les erreurs prédéfinies du serveur Oracle Pour intercepter une erreur prédéfinie du serveur Oracle, utilisez son nom standard dans le sous-programme correspondant de traitement des exceptions. Remarque : En PL/SQL, les exceptions prédéfinies sont déclarées dans le package STANDARD. Il est conseillé de traiter systématiquement les exceptions NO_DATA_FOUND et TOO_MANY_ROWS, qui sont les plus usuelles.
28
Exception prédéfinie Syntaxe : BEGIN SELECT ... COMMIT; EXCEPTION
WHEN NO_DATA_FOUND THEN statement1; statement2; WHEN TOO_MANY_ROWS THEN WHEN OTHERS THEN statement3; END; Intercepter les exceptions prédéfinies du serveur Oracle Dans l'exemple présenté sur la diapositive, à chaque exception, l'utilisateur voit s'afficher un message. Une seule une exception est déclenchée et traitée à tout moment.
29
Erreur non prédéfinie Intercepter une violation de contrainte d'intégrité (code d'erreur du serveur Oracle -2292) DECLARE e_products_invalid EXCEPTION; PRAGMA EXCEPTION_INIT ( e_products_invalid, -2292); v_message VARCHAR2(50); BEGIN . . . EXCEPTION WHEN e_products_invalid THEN :g_message := 'Product ID specified is not valid.'; END; 1 1 2 2 3 Intercepter une exception non prédéfinie du serveur Oracle 1. Déclarez le nom de l'exception dans la section déclarative. Syntaxe exception EXCEPTION; où :exception correspond au nom de l'exception. 2. Utilisez l'instruction PRAGMA EXCEPTION_INIT pour associer l'exception déclarée au code d'erreur standard du serveur Oracle. PRAGMA EXCEPTION_INIT(exception, error_number); où :exception correspond à l'exception déclarée préalablement. error_number correspond à un code d'erreur standard du serveur Oracle. 3. Faites référence à l'exception ainsi déclarée dans le sous-programme de traitement des exceptions correspondant. L'exemple présenté sur la diapositive a la signification suivante : si un produit existe en stock, arrêter le traitement et afficher un message à l'utilisateur.
30
Exception définie par l'utilisateur
Exemple : [DECLARE] e_amount_remaining EXCEPTION; . . . BEGIN RAISE e_amount_remaining; EXCEPTION WHEN e_amount_remaining THEN :g_message := 'There is still an amount in stock.'; END; 1 2 3 Intercepter les exceptions définies par l'utilisateur Pour intercepter une exception définie par l'utilisateur, vous devez la déclarer et la déclencher explicitement. 1. Déclarez le nom de l'exception définie par l'utilisateur dans la section déclarative. Syntaxe exception EXCEPTION; où :exception correspond au nom de l'exception. 2. Utilisez l'instruction RAISE pour déclencher explicitement l'exception dans la section exécutable. RAISE exception; où :exception correspond à l'exception déclarée préalablement. 3. Faites référence à l'exception ainsi déclarée dans le sous-programme correspondant de traitement des exceptions. L'exemple présenté sur la diapositive a la signification suivante : le client dispose d'une règle qui établit qu'un produit ne doit pas être supprimé de sa base de données s'il est encore en stock. Etant donné qu'il n'existe aucune contrainte pour appliquer cette règle, le développeur la traite explicitement dans l'application. Avant d'effectuer une suppression (DELETE) dans la table PRODUCT_INFORMATION, le bloc interroge la table INVENTORIES pour vérifier si le produit concerné n'existe pas en stock. S'il existe effectivement, une exception est déclenchée. Remarque : Utilisez l'instruction RAISE dans un gestionnaire d'exceptions pour renvoyer la même exception à l'environnement appelant.
31
RAISE_APPLICATION_ERROR
Syntaxe : Procédure qui permet de délivrer des messages d'erreur définis par l'utilisateur à partir de sous-programmes stockés Elle est appelée uniquement à partir d'un sous-programme stocké en cours d'exécution raise_application_error (error_number, message[, {TRUE | FALSE}]); RAISE_APPLICATION_ERROR Grâce à la procédure RAISE_APPLICATION_ERROR, délivrez de manière interactive une exception prédéfinie en renvoyant un code et un message d'erreur non-standard. RAISE_APPLICATION_ERROR permet de signaler les erreurs à l'application et d'éviter le renvoi d'exceptions non traitées. Dans la syntaxe, error_number est une valeur numérique définie par l'utilisateur pour l'exception ; cette valeur est comprise entre et message est un message défini par l'utilisateur pour l'exception ; il s'agit d'une chaîne de caractères d'une taille maximale de 2048 octets. TRUE | FALSE est un paramètre booléen facultatif. Si le paramètre est TRUE, l'erreur est rangée dans la pile des erreurs précédentes. Si le paramètre est FALSE (valeur par défaut), l'erreur remplace toutes les erreurs précédentes. Exemple ... EXCEPTION WHEN NO_DATA_FOUND THEN RAISE_APPLICATION_ERROR (-20201, 'Manager is not a valid employee.'); END;
32
RAISE_APPLICATION_ERROR
Elle peut être utilisée à deux endroits : section exécutable section de traitement des exceptions Elle renvoie à l'utilisateur les conditions de l'erreur de manière cohérente par rapport aux autres erreurs du serveur Oracle Exemple ... DELETE FROM employees WHERE manager_id = v_mgr; IF SQL%NOTFOUND THEN RAISE_APPLICATION_ERROR(-20202,'This is not a valid manager'); END IF;
Présentations similaires
© 2024 SlidePlayer.fr Inc.
All rights reserved.