Vous êtes sur la page 1sur 4

M1 Informatique – Année 2017-2018

Bases de données avancées


TD n° 3 (PL/SQL) : Procédures stockées et paquetages
J. Darmont (http://eric.univ-lyon2.fr/~jdarmont/), 12/09/17

Débogage des procédures stockées

Si la définition d’une procédure stockée, d’une fonction stockée, d’un paquetage, d’un corps de paquetage
ou d’un déclencheur est incorrecte, Oracle indique la création « avec des erreurs de compilation », sans plus
de précision. Pour visualiser les erreurs, utiliser la commande suivante.

SHOW ERRORS

Exercice 1 : Procédure stockée

1. Reprendre le bloc PL/SQL anonyme permettant d’afficher le nom et le prix des 5 produits les plus chers
de la table DEMO_PRODUCT_INFO (TD n° 1, Exercice 3) et le transformer en procédure stockée.

2. Exécuter la procédure stockée.

3. Modifier la procédure stockée pour qu’elle affiche les k produits les plus chers.

4. Tester l’exécution de la procédure stockée avec plusieurs valeurs de k (dont des valeurs supérieures à
10).

Exercice 2 : Paquetage

Il s’agit d’implémenter un paquetage permettant de gérer la table DEMO_STATES(ST, STATE_NAME).


L’objectif est de proposer des procédures et des fonctions permettant de :
• afficher le contenu de la table au format ST : STATE_NAME ;
• ajouter un état ;
• modifier le nom d’un état connaissant son code ST ;
• supprimer un état connaissant son code ST ;
• compter le nombre d’états.

1. Recopier la table DARMONT.DEMO_STATES sur votre compte.

2. Définir la spécification d’un paquetage nommé statepack contenant :


• un type enregistrement nommé statetuple avec les champs code et name, de mêmes types que les
attributs ST et STATE_NAME de la table DEMO_STATES, respectivement ;
• un curseur nommé statelist qui renvoie un statetuple.

3. Définir le corps du paquetage statepack en spécifiant complètement le curseur statelist. Lancer


(séparément) la création de la spécification et du corps de statepack.

4. Ajouter à la spécification et au corps du paquetage statepack une procédure nommée display (sans
paramètre) qui affiche tous les états à l’écran dans le format désiré. Dans le code de la procédure display,
utiliser le curseur statelist et une variable enregistrement locale de type statetuple. Tester la procédure
(EXECUTE statepack.display ou BEGIN statepack.display; END;).

5. Ajouter à la spécification et au corps du paquetage statepack une procédure nommée add qui insère dans
la table DEMO_STATES un nouvel état dont le code ST et le nom sont passés en paramètres. Tester la
procédure.

6. Ajouter à la spécification et au corps du paquetage statepack une procédure nommée mod qui modifie
dans la table DEMO_STATES l’état dont le code ST et le nouveau nom sont passés en paramètres. Tester
la procédure.

M1 Informatique – Bases de données avancées – TD 3 1/2


7. Ajouter à la spécification et au corps du paquetage statepack une procédure nommée del qui supprime de
la table DEMO_STATES l’état dont le code ST est passé en paramètre. Tester la procédure.

8. Ajouter uniquement au corps du paquetage statepack une fonction nommée statecount qui renvoie le
nombre d’états dans la table DEMO_STATES. Tester la fonction depuis l’extérieur du paquetage (EXECUTE
DBMS_OUTPUT.PUT_LINE(statepack.statecount)). Conclusion ?

9. Appeler la fonction statecount au sein de la procédure display et afficher le résultat au format « NN


état(s) » sous la liste des états déjà établie. Où la fonction statecount doit-elle être définie dans le corps du
paquetage ? Comment fonction statecount peut-elle être qualifiée ?

M1 Informatique – Bases de données avancées – TD 3 2/2


Correction

-- Exercice 1

CREATE OR REPLACE PROCEDURE topk(k NUMBER) IS


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 <= k LOOP
DBMS_OUTPUT.PUT_LINE(ranking%ROWCOUNT || ') ' || p.product_name ||
' : ' || p.list_price || ' €');
FETCH ranking INTO p; -- Produit suivant
END LOOP;
CLOSE ranking;
END;

-- Exécution sous SQL Developer


EXECUTE topk(6)

-- Exécution dans un bloc PL/SQL


BEGIN
topk(20);
END;

-- Exercice 2

-- Spécification du paquetage

CREATE OR REPLACE PACKAGE statepack AS

TYPE statetuple IS RECORD(


code demo_states.st%TYPE,
name demo_states.state_name%TYPE);

CURSOR statelist RETURN statetuple;

PROCEDURE display;

PROCEDURE add(
code demo_states.st%TYPE,
name demo_states.state_name%TYPE);

PROCEDURE mod(
code demo_states.st%TYPE,
newname demo_states.state_name%TYPE);

PROCEDURE del(code demo_states.st%TYPE);

END; -- Fin de la spécification


/
SHOW ERRORS

M1 Informatique – Bases de données avancées – TD 3 3/2


-- Corps du paquetage

CREATE OR REPLACE PACKAGE BODY statepack AS

CURSOR statelist RETURN statetuple IS


SELECT * FROM demo_states;

FUNCTION statecount RETURN INTEGER IS


-- Pas présente dans la spécification => privée
c INTEGER;
BEGIN
SELECT COUNT(*) INTO c FROM demo_states;
RETURN c;
END;

PROCEDURE display IS
s statetuple;
BEGIN
FOR s IN statelist LOOP
DBMS_OUTPUT.PUT_LINE(s.code || ': ' || s.name);
END LOOP;
DBMS_OUTPUT.PUT_LINE(statecount || ' state(s)');
END;

PROCEDURE add(
code demo_states.st%TYPE,
name demo_states.state_name%TYPE) IS
BEGIN
INSERT INTO demo_states VALUES(code, name);
END;

PROCEDURE mod(
code demo_states.st%TYPE,
newname demo_states.state_name%TYPE) IS
BEGIN
UPDATE demo_states SET state_name = newname WHERE st = code;
END;

PROCEDURE del(code demo_states.st%TYPE) IS


BEGIN
DELETE FROM demo_states WHERE st = code;
END;

END; -- Fin du corps


/
SHOW ERRORS

-- Tests

EXECUTE statepack.display
EXECUTE statepack.add('ZZ', 'test')
EXECUTE statepack.display
EXECUTE statepack.mod('ZZ', 'test plus long')
EXECUTE statepack.display
EXECUTE statepack.del('ZZ')
EXECUTE statepack.display
EXECUTE DBMS_OUTPUT.PUT_LINE(statepack.statecount) -- ne fonctionne pas
EXECUTE statepack.display

M1 Informatique – Bases de données avancées – TD 3 4/2