Académique Documents
Professionnel Documents
Culture Documents
Aide-mémoire PL/SQL
Soit la table EMP qui stocke des informations sur les employés d’une entreprise. On souhaite déterminer la
proportion de managers parmi eux.
1. Recopier la table DARMONT.EMP sur votre compte, sous le nom EMP à l’aide de la requête SQL
CREATE TABLE emp AS SELECT * FROM darmont.emp.
3. Tester !
4. Inclure dans le programme précédent un traitement d’exception permettant de détecter si la table EMP est
vide, c’est-à-dire, que le nombre total de n-uplets dans EMP est égal à zéro. Dans ce cas, déclencher une
erreur fatale (on ne peut pas permettre une division par zéro). Tester le bon fonctionnement de l’exception
en suivant la procédure suivante :
1. valider les mises à jour précédentes à l’aide de la commande SQL COMMIT (ou touche F11) ;
2. effacer le contenu de la table EMP (DELETE FROM emp) ;
3. exécuter le bloc PL/SQL ;
4. annuler l’effacement de la table EMP à l’aide de la commande SQL ROLLBACK (ou touche F12).
1. Créer une vue quelconque (ex. CREATE VIEW nom_emp AS SELECT ename FROM emp).
2. Écrire un bloc PL/SQL anonyme permettant d’afficher votre catalogue système (liste des tables et des
vues de votre compte disponible grâce à la vue système TAB) sous la forme :
L’objet UNE_TABLE est de type TABLE.
L’objet UNE_AUTRE_TABLE est de type TABLE.
L’objet UNE_VUE est de type VIEW.
…
Indication : Tester au préalable sous SQL l’exécution de la requête SELECT * FROM TAB pour avoir une
idée du contenu de la vue système TAB.
2. Écrire un bloc PL/SQL anonyme permettant d’afficher le nom (PRODUCT_NAME) et le prix (LIST_PRICE)
des 5 produits les plus chers de la table DEMO_PRODUCT_INFO.
Indications :
• Définir un curseur qui liste les produits par ordre de prix décroissant.
• Effectuer un parcours explicite du curseur qui s’arrête tant que 5 n-uplets n’ont pas été lus.
Afin d’établir une corrélation, on souhaite connaître la différence de quantité moyenne entre les commandes
successivement enregistrées dans une table de commandes (ORD). La table ORD est remplie de
commandes valuées (c’est-à-dire, pour lesquelles l’attribut quantité QTY n’est pas NULL) ou non. Les
commandes non valuées ne sont pas à prendre en compte. Écrire un bloc PL/SQL anonyme permettant de
calculer la différence de quantité moyenne entre les commandes. Pour simplifier, on pourra la réduire la
table ORD à l’unique attribut QTY.
Exemple :
QTY
5
NULL
10 Résultat attendu = ( |10 – 5| + |8 – 10| + |9 – 8| + |13 – 9| ) / 4 = 3
8
9
13
Indications :
• Recopier la table DARMONT.ORD sur votre compte.
• Créer un curseur contenant les quantités des commandes valuées (…WHERE QTY IS NOT NULL).
• À l’aide d’un parcours explicite du curseur, lire la première quantité puis, pour toutes les quantités
suivantes, cumuler la valeur absolue de quantité courante – quantité précédente (fonction ABS).
• Exception : Interrompre le programme immédiatement si la table ORD contient moins de deux
contraintes values. Pour ce type de traitements, on utilise habituellement une requête COUNT.
-- Exercice 1
DECLARE
ntot INTEGER; -- Nombre total d’employés
nman INTEGER; -- Nombre de managers
pman REAL; -- Proportion de managers
personne EXCEPTION; -- Exception : pas d’employés
BEGIN
SELECT COUNT(*) INTO ntot FROM emp;
IF (ntot = 0) THEN
RAISE personne;
END IF;
EXCEPTION
WHEN personne THEN
RAISE_APPLICATION_ERROR(-20500, 'La table EMP est vide !');
END;
-- Exercice 2
DECLARE
CURSOR catalogue IS SELECT tname, tabtype FROM tab;
ligne catalogue%ROWTYPE;
BEGIN
FOR ligne IN catalogue LOOP
DBMS_OUTPUT.PUT_LINE('L''objet ' || ligne.tname || ' est de type ' ||
ligne.tabtype || '.');
END LOOP;
END;
-- Exercice 3
DECLARE
CURSOR ranking IS SELECT product_name, list_price FROM demo_product_info
ORDER BY list_price DESC;
p ranking%ROWTYPE;
BEGIN
OPEN ranking;
FETCH ranking INTO p; -- Premier produit
WHILE ranking%FOUND AND ranking%ROWCOUNT <= 5 LOOP
DBMS_OUTPUT.PUT_LINE(ranking%ROWCOUNT || ') ' || p.product_name ||
' : ' || p.list_price || ' €');
FETCH ranking INTO p; -- Produit suivant
END LOOP;
CLOSE ranking;
END;
DECLARE
CURSOR com_val IS
SELECT qty FROM ord WHERE qty IS NOT NULL;
prec com_val%ROWTYPE; -- n-uplet précédent
cour com_val%ROWTYPE; -- n-uplet courant
total REAL := 0;
n_val INTEGER;
pas_assez EXCEPTION;
BEGIN
-- Test du nombre de commandes valuées
SELECT COUNT(*) INTO n_val FROM ord WHERE qty IS NOT NULL;
IF n_val < 2 THEN
RAISE pas_assez;
END IF;
EXCEPTION
WHEN pas_assez THEN
RAISE_APPLICATION_ERROR(-20501, 'Pas assez de commandes !');
END;