Interactions avec le Serveur Oracle
Transcription
Interactions avec le Serveur Oracle
Mostafa Hanoune 3 Interactions avec le Serveur Oracle Mostafa Hanoune Objectifs A la fin de ce chapitre, vous saurez : • Ecrire une instruction SELECT en PL/SQL • Déclarer le type de données et la taille d’une variable PL/SQL dynamiquement • Ecrire des instructions LMD en PL/SQL • Contrôler les transactions en PL/SQL • Déterminer l’issue des instructions LMD 3-2 Objectifs Dans ce chapitre, vous allez apprendre à intégrer les instructions standard SQL SELECT, INSERT, UPDATE, et DELETE dans des blocs PL/SQL. Vous apprendrez aussi à contrôler les transactions et à déterminer l’issue des instructions SQL de type LMD en PL/SQL. Les Bases PL/SQL 3-2 Mostafa Hanoune Instructions SQL en PL/SQL • Extraire une ligne de la base de grâce à la commande SELECT. Un seul jeu de valeurs peut être retourné. • Modifiez des lignes dans la base en utilisant des commandes LMD. • Contrôlez une transaction avec les commandes COMMIT, ROLLBACK, ou SAVEPOINT. • Déterminez l’issue d’une commande LMD avec des curseurs implicites. 3-3 Vue d’ensemble Lorsque vous avez besoin d’extraire ou de modifier des informations de la base de données, vous devez utiliser le SQL. Le PL/SQL permet la manipulation des données, ainsi que le contrôle des transactions avec le SQL. Vous pouvez utiliser des instructions SELECT pour remplir des variables avec des valeurs extraites d’un enregistrement d’une table. Vos commandes LMD (Langage de Manipulation de Données) peuvent traiter plusieurs enregistrements à la fois. Comparaison des instructions SQL et PL/SQL • Un bloc PL/SQL n’est pas une unité de transaction. Les COMMIT, SAVEPOINT, et ROLLBACK sont indépendants des blocs, mais vous pouvez utiliser ces commandes dans un bloc. • Le PL/SQL ne permet pas le langage de définition des données (LDD), à savoir les instructions comme CREATE TABLE, ALTER TABLE, ou DROP TABLE... • Le PL/SQL ne permet pas le langage de contrôle des données (LCD), à savoir les instructions telles que GRANT ou REVOKE. Pour plus d’informations sur le package DBMS_SQL, voir Oracle8 Server Application Developer’s Guide, Release 8. Note au formateur Vous pouvez mentionner qu’avec le module DBMS_SQL, on peut utiliser des instructions LDD et LCD. Les Bases PL/SQL 3-3 Mostafa Hanoune Instructions SELECT en PL/SQL Extraire une ligne de la base de données avec SELECT. Syntaxe SELECT select_list INTO {variable_name[, variable_name]... | record_name} FROM table WHERE condition; 3-4 Extraire des données en utilisant PL/SQL Utilisez l’instruction SELECT pour extraire des données de la base de données. Dans la syntaxe: select_list est une liste comprenant au moins une colonne, où peuvent figurer des expressions SQL, des fonctions mono-ligne, ou des fonctions de variable_name est une variable scalaire qui contiendra la valeur extraite record_name est l’enregistrement PL/SQL qui contiendra les valeurs extraites table spécifie le nom de la table de la base de données condition est composée du noms de colonnes, d’expressions, de constantes, et d’opérateurs de comparaison, ainsi que de variables et constantes PL/SQL groupe Vous pouvez profiter de l’étendue de l’instruction SELECT sur le Serveur Oracle. Souvenez-vous que les variables hôtes doivent être précédées d’un deux points (:). Les Bases PL/SQL 3-4 Mostafa Hanoune Instructions SELECT en PL/SQL La clause INTO est Obligatoire. Exemple : DECLARE v_deptno v_loc BEGIN SELECT INTO FROM WHERE ... END; NUMBER(2); VARCHAR2(15); deptno, loc v_deptno, v_loc dept dname = 'SALES'; 3-5 Clause INTO La clause INTO est obligatoire, et apparaît entre les clauses SELECT et FROM. Elle est utilisée pour spécifier les noms des variables qui contiendront les valeurs retournées par l’ordre SELECT. Vous devez prévoir une variable pour chaque élément ramené, et leur ordre doit correspondre à celui des éléments sélectionnés. On utilise une clause INTO pour remplir des variables PL/SQL ou des variables hôtes. Les Requêtes Doivent RamenerUn et Un Seul Enregistrement Les instructions SELECT dans un bloc PL/SQL respectent la norme ANSI du SQL, selon laquelle les requêtes doivent retourner un enregistrement et un seul. Le retour de plusieurs enregistrements, ou d’aucun enregistrement engendre une erreur. Le PL/SQL gère ces erreurs en suscitant des exceptions standards, que vous pouvez intercepter dans la section EXCEPTION du bloc grâce aux exceptions NO_DATA_FOUND et TOO_MANY_ROWS (la gestion des exceptions est traitée dans un chapitre ultérieur). Vous devez utiliser les instructions SELECT si la requête ne ramène qu’un seul enregistrement. Note au formateur La clause INTO est obligatoire dans l’instruction SELECT en PL/SQL. Cela s’oppose au SQL, ou la clause INTO est interdite. Les Bases PL/SQL 3-5 Mostafa Hanoune Extraire des données en PL/SQL Extraire la date de commande et la date d’expédition pour la commande spécifiée. Exemple DECLARE v_orderdate ord.orderdate%TYPE; v_shipdate ord.shipdate%TYPE; BEGIN SELECT orderdate, shipdate INTO v_orderdate, v_shipdate FROM ord WHERE id = 620; ... END; 3-6 Règles générales Suivez ces indications générales pour extraire des données en PL/SQL : • Terminez chaque instruction SQL avec un point virgule (;). • La clause INTO est obligatoire pour un ordre SELECT dans un bloc PL/SQL. • La clause WHERE est optionnelle et peut être utilisée pour spécifier des variables d’entrée, des constantes, des valeurs, ou des expressions PL/SQL. • Spécifiez le même nombre de variables en sortie dans la clause INTO que le nombre de colonnes ramenées dans la clause SELECT. Assurez-vous que l’ordre est exact, et que les types de données sont compatibles. Note au formateur Les variables de sortie sont des variables PL/SQL par lesquelles une valeur est transmise de la base de données vers le bloc PL/SQL. Le type de données de la variable de sortie doit être compatible avec celui de la colonne source, bien que la colonne source puisse être une expression; en particulier, les variables booléennes ne sont pas permises. Les variables d’entrée sont des variables PL/SQL par lesquelles une valeur est transmise du bloc PL/SQL vers la base de données. Les Bases PL/SQL 3-6 Mostafa Hanoune Extraire des données en PL/SQL Retournez la somme des salaires de tous les employés du service spécifié. Exemple DECLARE v_sum_sal v_deptno BEGIN SELECT INTO FROM WHERE END; emp.sal%TYPE; NUMBER NOT NULL := 10; SUM(sal) -- group function v_sum_sal emp deptno = v_deptno; 3-7 Règles générales(suite) • Pour vous assurez que les types de données des identifiants correspondent à ceux des colonnes, utilisez l’attribut %TYPE. Le type de données et le nombre de variables de la clause INTO doivent correspondre à ceux de la liste du SELECT. • Utilisez les fonctions de groupe, telles que SUM, dans une instruction SQL pour réaliser des calculs sur un ensemble de lignes d’une table. Note : Les fonctions de groupe ne sont pas directement utilisables en PL/SQL. Elles sont utilisées dans des instructions SQL à l’intérieur d’un bloc PL/SQL. Note au formateur Au tableau, écrivez : v_somme_salaires := SUM(emp.sal); et rayez cette instruction pour souligner le fait qu’il faut utiliser des fonctions de groupe dans une instruction SQL. Les Bases PL/SQL 3-7 Mostafa Hanoune Manipuler des données en PL/SQL Modifiez le contenu des tables de la base de données à l’aide des commandes LMD suivantes : • INSERT INSERT • UPDATE • DELETE UPDATE DELETE 3-8 Manipuler les Données en PL/SQL On manipule les données de la base à l’aide de commandes LMD (Manipulation des Données). Vous pouvez utiliser les commandes LMD INSERT, UPDATE, et DELETE sans restriction en PL/SQL. En incluant des instructions COMMIT ou ROLLBACK dans le code PL/SQL vous levez ainsi les verrous posés sur les enregistrements modifiés (ainsi que sur les tables). • L’instruction INSERT ajoute de nouveaux enregistrements à la table. • L’instruction UPDATE modifie les enregistrements existants dans la table. • L’instruction DELETE supprime les enregistrements dans la table. Les Bases PL/SQL 3-8 Mostafa Hanoune Insérer des données Ajoutez les informations concernant un nouvel employé à la table emp. Exemple BEGIN INSERT INTO emp(empno, ename, job, deptno) VALUES(empno_sequence.NEXTVAL, 'HARDING', 'CLERK', 10); END; 3-9 Insérer des données • Utilisez les fonctions SQL telles que USER et SYSDATE. • Générez des valeurs de clé primaire en utilisant les séquences de la base de données. • Prenez des valeurs dans les blocs PL/SQL. • Choisissez des valeurs par défaut pour les colonnes. Remarque : Il n’y a aucune ambiguïté possible entre les identifiants et les noms de colonnes dans l’instruction INSERT. Tout identifiant de la clause INSERT doit être un nom de colonne de la base de données. Note au formateur Démo : l3insert.sql Objectif : Cet exemple illustre l’utilisation de l’instruction INSERT dans un bloc anonyme. Vérifiez que le changement a bien lieu dans la table. Entrez SELECT * FROM emp où empno est le numéro d’employé saisi. Les Bases PL/SQL 3-9 Mostafa Hanoune Mettre à jour des données Augmentez le salaire de tous les employés de la table emp dont la fonction est Analyste. Exemple DECLARE v_sal_increase emp.sal%TYPE := 2000; BEGIN UPDATE emp SET sal = sal + v_sal_increase WHERE job = 'ANALYST'; END; 3-10 Mettre à jour des Données Il peut y avoir une ambiguïté dans la clause SET de l’instruction UPDATE car bien que l’identifiant à gauche de l’opérateur d’affectation soit toujours une colonne de la base de données, l’identifiant à droite peut être soit une colonne de la base de données soit une variable PL/SQL. Souvenez vous que la clause WHERE est utilisée pour déterminer quels enregistrements sont modifiés. Si aucun enregistrement n’est modifié, aucune erreur ne se produit, contrairement à l’instruction SELECT en PL/SQL. Remarque : Les affectations de variables PL/SQL utilisent toujours (:=) tandis que les affectations de colonnes SQL utilisent toujours( =). Souvenez vous que si, dans une clause WHERE, le nom de colonne et le nom d’identifiant sont les mêmes, alors le Serveur Oracle cherche d’abord le nom de la colonne. Note au formateur Démo : l3insert.sql Objectif : Cet exemple illustre l’utilisation de l’instruction UPDATE dans un bloc anonyme. Vérifiez que le changement a bien lieu dans la table. Entrez SELECT * FROM emp. Les Bases PL/SQL 3-10 Mostafa Hanoune Supprimer des données Supprimez les enregistrements dont le département est le 10 dans la table emp. Exemple DECLARE v_deptno emp.deptno%TYPE := 10; BEGIN DELETE FROM emp WHERE deptno = v_deptno; END; 3-11 Supprimer des données Supprimez une commande spécifiée. DECLARE v_ordid ord.ordid%TYPE := 605; BEGIN DELETE FROM item WHERE ordid = v_ordid; END; Note au formateur Démo : l3insert.sql Objectif : Cet exemple illustre l’utilisation de l’instruction DELETE dans un bloc anonyme. Vérifiez que le changement a bien lieu dans la table. Entrez SELECT * FROM emp où deptno est le numéro de département et ’CLERK' est la fonction. Les Bases PL/SQL 3-11 Mostafa Hanoune Conventions d’appellation • Utilisez une convention d’appellation pour éviter toute ambiguïté dans la clause WHERE. • Les colonnes de la base de données et les identifiants doivent avoir des noms différents. • Des erreurs de syntaxe peuvent survenir car PL/SQL cherche d’abord dans la base une colonne de la table. 3-12 Les Bases PL/SQL 3-12 Mostafa Hanoune Conventions d’appellation DECLARE orderdate ord.orderdate%TYPE; shipdate ord.shipdate%TYPE; ordid ord.ordid%TYPE := 601; BEGIN SELECT orderdate, shipdate INTO orderdate, shipdate FROM ord WHERE ordid = ordid; END; SQL> / DECLARE * ERROR at line 1: ORA-01422: exact fetch returns more than requested number of rows ORA-06512: at line 6 3-13 Conventions d’Appellation Évitez toute ambiguïté dans la clause WHERE en optant pour une convention d’appellation qui distingue les noms de colonnes de la base de données des noms de variables PL/SQL. • Les colonnes de la base de données et les identifiants doivent avoir des noms distincts. • Des erreurs de syntaxe peuvent survenir car le PL/SQL cherche d’abord dans la base de données une colonne de la table. L’exemple de la diapositive est le suivant : Extraire la date de commande et la date d’expédition de la table ORD pour la commande numéro 601. Cet exemple génère une erreur d’exécution. Le PL/SQL vérifie si l’identifiant est une colonne de la base de données ; si ce n’est pas le cas, alors on suppose qu’il s’agit d’un identifiant PL/SQL. Note : Il ne peut y avoir d’ambiguïté dans une clause SELECT car tout identifiant doit être un nom de colonne de la base de données. Il ne peut y avoir d’ambiguïté dans une clause INTO car les identifiants doivent être des variables PL/SQL. La confusion ne peut exister que dans la clause WHERE. Un chapitre suivant donnera plus d’informations sur l’exception TOO_MANY_ROWS et les autres exceptions. Les Bases PL/SQL 3-13 Mostafa Hanoune Instructions COMMIT et ROLLBACK • Une transaction est initialisée par la première commande LMD, et doit être suivi d’un COMMIT ou d’un ROLLBACK. • Utilisez les instructions SQL COMMIT ou ROLLBACK pour terminer de façon explicite une transaction. 3-14 Contrôler des transactions Vous pouvez contrôler le déroulement des transactions avec les instructions SQL COMMIT et ROLLBACK, en rendant permattantes les modifications ou en abandonnant les autres. De même qu’avec le Serveur Oracle, les transactions commencent à la première commande LMD qui suit un COMMIT ou ROLLBACK, et s’achèvent au COMMIT ou ROLLBACK suivant. Ces actions peuvent avoir lieu dans un bloc PL/SQL ou résulter d’événements dans l’environnement hôte (par exemple, le fait d’achever une session SQL*Plus, termine automatiquement la transaction en cours). Pour mettre un point intermédiaire en cours de transaction, utilisez SAVEPOINT. Syntaxe COMMIT [WORK]; SAVEPOINT savepoint_name; ROLLBACK [WORK]; ROLLBACK [WORK] TO [SAVEPOINT] savepoint_name; où : WORK permet de se conformer aux standards ANSI Note : Les commandes de contrôle des transactions sont toutes valides en PL/SQL, bien que l’environnement hôte puisse en restreindre l’utilisation. Vous pouvez aussi inclure des commandes de verrouillage explicite (telles que LOCK TABLE et SELECT ... FOR UPDATE) dans un bloc (un chapitre ultérieur traitera de façon plus complète la commande FOR UPDATE). Elles restent en vigueur jusqu’à la fin de la transaction. Par ailleurs, un bloc PL/SQL n’implique pas nécessairement une transaction. Les Bases PL/SQL 3-14 Mostafa Hanoune Curseur SQL • Un curseur est une zone de travail réservée à SQL. • Il y a deux types de curseurs: – Curseurs implicites – Curseurs explicites • Le Serveur Oracle utilise les curseurs implicites pour analyser et exécuter les instructions SQL. • Les curseurs explicites sont déclarés de façon explicite par le programmeur. 3-15 Curseur SQL Lorsque vous utilisez une instruction SQL, le Serveur Oracle alloue une zone mémoire dans laquelle la commande est analysée. Cette zone est appelée un curseur implicite. Lorsque la partie exécutable d’un bloc appelle une instruction SQL, le PL/SQL crée un curseur implicite, qui porte l’identifiant : SQL. Le PL/SQL gère automatiquement ce curseur. Le programmeur pourra déclarer des curseurs explicites. Il y a quatre attributs applicables aux curseurs en PL/SQL. Remarque : Le chapitre suivant traite plus en détail les curseurs explicites. Pour plus d’informations, voir PL/SQL User’s Guide and Reference, Release 8, “Interaction with Oracle.” Les Bases PL/SQL 3-15 Mostafa Hanoune Attributs d’un curseur SQL Grâce aux attributs d’un curseur SQL, vous pouvez tester l’issue de vos instructions SQL. SQL%ROWCOUNT Nombre d’enregistrements traités par la dernière instruction SQL (une valeur entière) SQL%FOUND Attribut booléen qui vaut TRUE si la dernière instruction SQL a traité un ou plusieurs enregistrements SQL%NOTFOUND Attribut booléen qui vaut TRUE si la dernière instruction SQL n’a traité aucun enregistrement SQL%ISOPEN Vaut toujours FALSE car PL/SQL ferme les curseurs implicites immédiatement après leur exécution 3-16 Attributs d’un curseur SQL Les attributs d’un curseur SQL vous permettent de voir ce qui s’est passé lorsque le dernier curseur implicite a été exécuté. Vous utilisez ces attributs dans des instructions PL/SQL au même titre que des fonctions. Vous ne pouvez pas les utiliser dans des instructions SQL. Vous pouvez utiliser les attributs SQL%ROWCOUNT, SQL%FOUND, SQL%NOTFOUND, et SQL%ISOPEN dans la section EXCEPTION d’un bloc pour obtenir des informations sur l’exécution des manipulations des données. Le PL/SQL ne considère pas qu’une instruction LMD, qui n’affecte aucun enregistrement, a échoué contrairement à l’instruction SELECT, qui dans ce cas retourne une exception. Note au formateur SQL%ISOPEN est cité ici dans un souci d’exhaustivité ; cet attribut est utilisé avec les curseurs explicites. Les Bases PL/SQL 3-16 Mostafa Hanoune Attributs d’un curseur SQL Supprimez les enregistrements qui ont un numéro de commande spécifié dans la table ITEM. Affichez le nombre d’enregistrements supprimés. Exemple VARIABLE rows_deleted VARCHAR2(30) DECLARE v_ordid NUMBER := 605; BEGIN DELETE FROM item WHERE ordid = v_ordid; :rows_deleted := (SQL%ROWCOUNT || ' rows deleted.'); END; / PRINT rows_deleted 3-17 Les Bases PL/SQL 3-17 Mostafa Hanoune Résumé • Intégration du SQL dans un bloc PL/SQL : SELECT, INSERT, UPDATE, DELETE • Intégration d’instructions de contrôle des transactions dans un bloc PL/SQL : COMMIT, ROLLBACK, SAVEPOINT 3-18 Les Bases PL/SQL 3-18 Mostafa Hanoune Résumé • Il y a deux types de curseurs : implicites et explicites. • Les attributs d’un curseur implicite permettent de vérifier l’issue des instructions LMD : – SQL%ROWCOUNT – SQL%FOUND – SQL%NOTFOUND – SQL%ISOPEN • Les curseurs explicites sont définis par le programmeur. 3-19 Les Bases PL/SQL 3-19 Mostafa Hanoune Présentation de l’Exercice • Créer un bloc PL/SQL pour sélectionner des données d’une table • Créer un bloc PL/SQL pour insérer des données dans une table • Créer un bloc PL/SQL pour mettre à jour des données d’une table • Créer un bloc PL/SQL pour supprimer un enregistrement d’une table 3-20 Aperçu de l’exercice Dans cet exercice, vous allez créer des procédures pour sélectionner, saisir, mettre à jour, et supprimer les informations d’une table, en utilisant les requêtes SQL de base et les instructions LMD dans un bloc PL/SQL. Les Bases PL/SQL 3-20 Exercice 3 1. Créez un bloc PL/SQL qui sélectionne le plus grand numéro de département (DEPTNO) de la table DEPT et le stocke dans une variable SQL*Plus. Affichez le résultat à l’écran. Enregistrez votre bloc PL/SQL dans le fichier p3q1.sql. G_MAX_DEPTNO ----------40 2. Modifiez le bloc PL/SQL que vous avez créé à la question 1 pour insérer un nouveau département dans la table DEPT. Enregistrez votre bloc PL/SQL dans le fichier p3q2.sql. a. Plutôt que d’afficher le numéro de département extrait dans la question 1, ajoutez 10 à ce numéro et utilisez ce nouveau numéro pour créer le nouveau département. b. Utilisez un paramètre de substitution SQL*Plus pour le nom du département. c. Laissez la localité(LOC) à la valeur NULL pour l’instant. d. Exécutez le bloc PL/SQL. Veuillez saisir le nom du département: EDUCATION PL/SQL procedure successfully completed. e. Affichez le nouveau département que vous avez créé. DEPTNO DNAME LOC ----- --------- ----50 EDUCATION 3. Créez un bloc PL/SQL qui mette à jour la localité (LOC) d’un département existant. Enregistrez votre bloc PL/SQL dans le fichier p3q3.sql. a. Utilisez un paramètre de substitution SQL*Plus pour le numéro du département (DEPTNO). b. Utilisez un paramètre de substitution SQL*Plus pour la localité du département (LOC). c. Testez le bloc PL/SQL . Veuillez saisir le numéro département: 50 Veuillez saisir la localité du département: LYON PL/SQL procedure successfully completed. Les Bases PL/SQL 3-21 Exercice 3 (suite) d. Affichez le numéro, le nom et la localité du département mis à jour. DEPTNO DNAME LOC ----- --------- --------------50 EDUCATION LYON e. Affichez le département que vous avez mis à jour. 4. Créez un bloc PL/SQL qui supprime le département créé à la question 2. Enregistrez votre bloc PL/SQL dans le fichier p3q4.sql. a. Utilisez un paramètre de substitution SQL*Plus pour le numéro de département. b. Affichez à l’écran le nombre d’enregistrements affectés. c. Testez le bloc PL/SQL. Veuillez saisir le numéro du département : 50 PL/SQL procedure successfully completed. G_RESULT ----------------------------------------------------------1 enregistrement(s) supprimé(s). d. Que se passe-t-il si vous entrez un numéro de département inexistant ? Veuillez saisir le numéro du département : 99 PL/SQL procedure successfully completed. G_RESULT ----------------------------------------------------------0 enregistrement(s) supprimé(s). e. Vérifiez que le département a bien été supprimé. no rows selected Les Bases PL/SQL 3-22