Vous êtes sur la page 1sur 3

Ecole Supérieure des Sciences et de la Technologie A.

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;

FOR un_service IN services LOOP


DBMS_OUTPUT.PUT_LINE(un_service.nos || ' : ' ||
un_service.intitule || ' (' || un_service.localisation ||
')');
END LOOP;

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;

-- Si pas de produits, exception


IF nbprod = 0 THEN
RAISE aucun_produit;
END IF;

-- Acces sequentiel a la table PRODUIT


-- Remplissage de la table PRODUIT2

FOR prod IN acces LOOP


INSERT INTO produit2 VALUES(prod.numprod, UPPER(prod.desi),
ROUND(NVL(prod.prixuni,0)/euro), prod.numfour);
END LOOP;

-- 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 ?

Écrire un bloc PL/SQL anonyme incluant la déclaration et l’initialisation de deux variables n1


et n2 et faisant appel à la procédure « noms_emp » en lui passant successivement ces
variables en paramètre.

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

CURSOR employes IS SELECT ename FROM emp;


e employes%ROWTYPE;

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;
/

Vous aimerez peut-être aussi