Académique Documents
Professionnel Documents
Culture Documents
U : 2020-2021
de Hammam Sousse Niveau : 2 LI
Département Electronique et Informatique Matière : Ingénierie des BDs
Enseignant : SAGAR Samya
TP n°4 – PL\SQL
Curseurs, Exceptions et Sous-programmes
CORRECTION
Exercice 1
Soit la table SERVICE (NOS, LOCALISATION, INTITULE)
1. Écrire un bloc PL/SQL anonyme permettant d’afficher les services de la table
SERVICE au format « numéro_service : intitulé (localisation) ».
NB : L’exploitation d’une requête qui retourne plusieurs n-uplets passe forcément par
l’utilisation d’un curseur.
2. Au cas où il n’y ait aucun n-uplet dans la table SERVICE, afficher un message
d’erreur (exception, mais pas erreur fatale).
Correction
DECLARE
CURSOR services IS SELECT * FROM service ORDER BY nos;
un_service services%ROWTYPE;
nbs INTEGER;
no_service EXCEPTION;
BEGIN
SELECT COUNT(*) INTO nbs FROM service;
IF nbs=0 THEN
RAISE no_service;
END IF;
EXCEPTION
WHEN no_service THEN DBMS_OUTPUT.PUT_LINE('La table
SERVICE est vide.');
END;
/
1
Exercice 2
Soit la table PRODUIT (NumProd, Desi, PrixUni)
On désire remplir, à partir de cette table, une table PRODUIT2 dont la structure existe déjà,
telle que :
• la désignation des produits soit écrite en majuscules ;
• le prix unitaire en francs des produits soit converti en euros (1 € = 6,55957 F). Le prix
en euros devra être entier (arrondir au prix le plus proche).
• Si un prix de la table PRODUIT est NULL, son prix en euros doit être 0.
Pour cela :
1. Tester si la table PRODUIT est vide. Si c’est le cas, la table PRODUIT2 devra
contenir uniquement le n-uplet (0,’Pas de produit’, NULL).
2. Dans le cas contraire, accéder séquentiellement à la table PRODUIT, à l’aide d’un
curseur, effectuer les transformations sur les champs et stocker le résultat dans la table
PRODUIT2.
3. Valider la transaction.
Correction
DECLARE
euro CONSTANT REAL := 6.55957;
nbprod NUMBER(3);
aucun_produit EXCEPTION;
CURSOR acces IS
SELECT numprod, desi, prixuni FROM produit;
prod acces%ROWTYPE;
BEGIN
-- Compte des produits
SELECT COUNT(*) INTO nbprod FROM PRODUIT;
-- Validation de la transaction
COMMIT;
EXCEPTION
WHEN aucun_produit THEN
INSERT INTO produit2
VALUES(0,'Pas de produit', NULL);
END;
/
2
Exercice 3
Soit la table EMP (EMPNO, ENAME, JOB, MGR#, HIREDATE, SAL, COMM, DEPTNO#)
1. Écrire un bloc PL/SQL anonyme permettant d’afficher les noms des n premiers
employés de la table EMP. Le nombre n pourra être stocké dans une variable.
Gérer le cas où n est plus grand que le nombre de n-uplets de la table EMP.
2. Transformer le bloc anonyme en procédure stockée nommée « noms_emp », la
variable n devenant un paramètre d’entrée. Tester depuis l’invite de commande
SQL*Plus (commandes EXECUTE noms_emp(3), puis EXECUTE noms_emp(45)
par exemple).
3. Quitter le client SQL*Plus, relancer SQL*Plus et exécuter à nouveau la procédure.
Conclusion ?
Correction
1. C’est la même que la question 2 sauf ajouter à la déclaration une
variable (n INTEGER).
Si n est plus grand que le nombre de n-uplets de la table EMP ;
afficher alors tous les employés.
2.
CREATE OR REPLACE PROCEDURE noms_emp(n INTEGER) IS
BEGIN
OPEN employes;
FETCH employes INTO e;
WHILE employes%FOUND AND employes%ROWCOUNT <= n LOOP
DBMS_OUTPUT.PUT_LINE(e.ename);
FETCH employes INTO e;
END LOOP;
CLOSE employes;
END;
/
3.
-- Bloc anonyme (test)
DECLARE
n1 INTEGER := 3;
n2 INTEGER := 70;
BEGIN
noms_emp(n1);
noms_emp(n2);
END;
/