Sie sind auf Seite 1von 3

2. Dfinir le corps du paquetage pilotes : dfinir compltement le curseur les_pilotes .

Tester
la cration du paquetage.

Universit Lumire Lyon 2, Facult de Sciences conomiques et de Gestion


Master dInformatique M2 spcialit IUP IDS Anne 2005-2006
Bases de donnes et programmation TD n 4
J. Darmont (http://eric.univ-lyon2.fr/~jdarmont/), 08/11/05

Rappel : Dbogage des procdures stockes

3. Ajouter aux spcifications et au corps du paquetage une procdure nomme afficher (pas de
paramtre) permettant dafficher les pilotes lcran au format dsir. Utiliser dans le corps de cette
procdure le curseur les_pilotes et une variable locale de type PilNUplet . Tester la procdure
(EXECUTE pilotes.afficher).

Si une procdure stocke ou une dfinition de paquetage ou de corps de paquetage nest pas
correcte, Oracle indique uniquement quelle a t cre avec des erreurs de compilation . Pour
visualiser ces erreurs, utiliser la commande suivante.

4. Ajouter aux spcifications et au corps du paquetage une procdure nomme ajouter


permettant dajouter dans la table PILOTE un pilote dont les numro, nom, prnom, ville et salaire
sont passs en paramtres. Tester la procdure.

SHOW ERRORS

5. Ajouter aux spcifications et au corps du paquetage une procdure nomme supprimer


permettant de supprimer de la table PILOTE un pilote dont le numro est pass en paramtre. Tester
la procdure.

Exercice 1 : Procdure stocke


1. crire un bloc PL/SQL anonyme permettant dafficher les noms des n premiers employs de la
table EMP du TD n 2 (il est possible de recopier la table DARMONT.EMP si vous nen disposez
plus). Le nombre n pourra tre stock dans une variable. Grer le cas o n est plus grand que le
nombre de n-uplets de la table EMP.
2. Transformer le bloc anonyme en procdure stocke nomme noms_emp , la variable n
devenant un paramtre dentre. Tester depuis linvite de commande SQL*Plus (commandes
EXECUTE noms_emp(3), puis EXECUTE noms_emp(45) par exemple).

6. Ajouter aux spcifications et au corps du paquetage une procdure nomme modifier


permettant de modifier dans la table PILOTE un pilote dont les numro, nom, prnom, ville et
salaire sont passs en paramtres. Tester la procdure.
7. Ajouter aux spcifications et au corps du paquetage une fonction nomme compter retournant
un entier et permettant de compter le nombre de n-uplets de la table PILOTE. Tester lappel de la
fonction laide de la commande EXECUTE de SQL*Plus, puis dans un bloc PL/SQL anonyme.

Exercice 3 : Requte dynamique (altration de schma paramtre)


3. Quitter le client SQL*Plus, relancer SQL*Plus et excuter nouveau la procdure noms .
Conclusion ?
4. crire un bloc PL/SQL anonyme incluant la dclaration et linitialisation de deux variables n1 et
n2 et faisant appel la procdure noms_emp en lui passant successivement ces variables en
paramtre.

1. Dans un bloc PL/SQL anonyme, dfinir une variable chane de caractres nomme Source et
lui affecter le nom dune table de votre compte. Dfinir une seconde variable chane de caractres
nomme Destination et lui affecter une valeur quelconque (par exemple, COPIE). Dans le code
du bloc PL/SQL, programmer la copie de la table Source dans la table Destination (cration
de la table Destination avec tous les attributs et tous les n-uplets de Source ). Tester.

Exercice 2 : Paquetage

2. Transformer votre bloc PL/SQL anonyme en procdure stocke prenant en paramtres la table
source et la table destination. Cela fonctionne-t-il ?

On dsire mettre en place un paquetage logiciel permettant de grer la table PILOTE du TD n 1 (il
est possible de recopier la table DARMONT.PILOTE si vous nen disposez plus). Lobjectif est de
disposer de procdures permettant de :

afficher le contenu de la table au format Numro : Prnom NOM (Ville) - Salaire ;


ajouter un pilote ;
supprimer un pilote (connaissant son numro) ;
modifier un pilote ;
compter les pilotes.

Exercice 4 : Requte dynamique (cration de vue paramtre)

1. Dfinir les spcifications dun paquetage nomm pilotes contenant :

un type enregistrement nomm PilNUplet contenant les champs suivants : num, nom,
prenom, vil, et sal. Utiliser exactement le types des champs de la table PILOTE ;

un curseur nomm les_pilotes retournant un PilNUplet .

BD et programmation TD n 4

3. Ajouter la mention AUTHID CURRENT_USER dans votre dfinition de procdure, aprs la dfinition
des paramtres (par exemple, CREATE OR REPLACE PROCEDURE copie(source VARCHAR,
destination VARCHAR) AUTHID CURRENT_USER IS). Tester. Quest-ce qui a chang ? Pourquoi
cette manipulation tait-elle superflue lorsque vous avez cr des procdures stockes dans les
exercices prcdents ?

1/3

1. crire une procdure stocke prenant en paramtre le nom dune table et permettant de crer une
vue contenant les noms de tous les attributs de cette table ainsi que leur type. Le nom de la vue
devra tre de la forme ATT_nom_de_la_table. Utiliser la vue systme USER_TAB_COLUMNS
(TABLE_NAME, COLUMN_NAME, DATA_TYPE) pour accder au nom et au type des attributs. Vrifier
le rsultat.

BD et programmation TD n 4

2/3

NB : Dans les vues systmes, toutes les chanes de caractres (comme les noms de tables ou
dattributs) sont stockes en majuscules.

Correction
-- Ex. 1

Exercice 5 : Curseur simple et requte dynamique (requte paramtre sur rsultat de requte)

CREATE OR REPLACE PROCEDURE noms_emp(n INTEGER) IS

crire une procdure stocke permettant de compter le nombre de n-uplets dans toutes les tables de
votre catalogue systme (vue systme TAB (TNAME, TABTYPE)). Exclure les vues (type VIEW) de
ce calcul. Afficher le rsultat tri par ordre alphabtique sous la forme NOM_TABLE : NB_NUPLETS
n-uplet(s). Grer le pluriel du mot n-uplet , qui prend un s uniquement quand la taille de la
table est strictement suprieure 1 n-uplet.

Exercice 6 complmentaire
crire une procdure stocke permettant de rechercher les tables contenant un attribut dont le nom
contient une chane de caractres passe en paramtres, ainsi que le nom, le type de cet attribut et le
nombre de valeurs distinctes de cet attribut dans la table.

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;
/
-- Bloc anonyme (test)
DECLARE
n1 INTEGER := 3;
n2 INTEGER := 70;
BEGIN
noms_emp(n1);
noms_emp(n2);
END;
/

-- Ex. 2
CREATE OR REPLACE PACKAGE pilotes AS
TYPE PilNUplet IS RECORD(
num pilote.plnum%TYPE,
nom pilote.plnom%TYPE,
prenom pilote.plprenom%TYPE,
vil pilote.ville%TYPE,
sal pilote.salaire%TYPE);
CURSOR les_pilotes RETURN PilNUplet;
PROCEDURE afficher;
PROCEDURE ajouter(num INTEGER, nom VARCHAR, prenom VARCHAR, vil VARCHAR,
sal REAL);
PROCEDURE supprimer(num INTEGER);
PROCEDURE modifier(num INTEGER, nom VARCHAR, prenom VARCHAR, vil VARCHAR,
sal REAL);
FUNCTION compter RETURN INTEGER;
END;
/

BD et programmation TD n 4

3/3

BD et programmation TD n 4

4/3

CREATE OR REPLACE PACKAGE BODY pilotes AS

-- Ex. 4

CURSOR les_pilotes RETURN PilNUplet IS SELECT * FROM pilote;

CREATE OR REPLACE PROCEDURE VueAtt(tabl VARCHAR) AUTHID CURRENT_USER IS


rq VARCHAR(255);

PROCEDURE afficher IS
t PilNUplet;
BEGIN
FOR t IN les_pilotes LOOP
DBMS_OUTPUT.PUT_LINE(t.num || ' : ' || t.prenom || ' ' || UPPER(t.nom)
|| ' (' || t.vil || ') - ' || t.sal);
END LOOP;
END;

BEGIN
rq := 'CREATE VIEW ATT_' || tabl || ' AS SELECT COLUMN_NAME, DATA_TYPE
FROM USER_TAB_COLUMNS WHERE TABLE_NAME=''' || UPPER(tabl) || '''';
EXECUTE IMMEDIATE rq;

PROCEDURE ajouter(num INTEGER, nom VARCHAR, prenom VARCHAR, vil VARCHAR,


sal REAL) IS
BEGIN
INSERT INTO pilote VALUES(num, nom, prenom, vil, sal);
END;

-- Ex. 5

END;
/

CREATE OR REPLACE PROCEDURE Compte IS

PROCEDURE supprimer(num INTEGER) IS


BEGIN
DELETE FROM pilote WHERE plnum=num;
END;

CURSOR tables IS SELECT TNAME FROM TAB WHERE TABTYPE <> 'VIEW'
ORDER BY TNAME;
t tables%ROWTYPE;
c INTEGER;
fin VARCHAR(9);

PROCEDURE modifier(num INTEGER, nom VARCHAR, prenom VARCHAR, vil VARCHAR,


sal REAL) IS
BEGIN
UPDATE pilote SET plnom=nom, plprenom=prenom, ville=vil, salaire=sal
WHERE plnum=num;
END;
FUNCTION compter RETURN INTEGER IS
n INTEGER;
BEGIN
SELECT COUNT(*) INTO n FROM pilote;
RETURN n;
END;

BEGIN
FOR t IN tables LOOP
EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM ' || t.TNAME INTO c;
IF c>1 THEN
fin := ' n-uplets';
ELSE
fin := ' n-uplet';
END IF;
DBMS_OUTPUT.PUT_LINE(t.TNAME || ' : ' || c || fin);
END LOOP;
END;
/

END;
/

-- Ex. 6

-- Test fonction compter

CREATE OR REPLACE PROCEDURE recherche(attribut VARCHAR) IS

BEGIN
DBMS_OUTPUT.PUT_LINE(pilotes.compter);
END;
/

CURSOR liste IS

SELECT TABLE_NAME, COLUMN_NAME, DATA_TYPE


FROM USER_TAB_COLUMNS
WHERE COLUMN_NAME LIKE UPPER('%' || attribut || '%')
ORDER BY TABLE_NAME;

t liste%ROWTYPE;
c INTEGER;
-- Ex. 3
CREATE OR REPLACE PROCEDURE copie(source VARCHAR, destination VARCHAR) AUTHID
CURRENT_USER IS
--DECLARE
-source VARCHAR(20) := 'EMP';
-destination VARCHAR(20) := 'EMP_COPIE';
BEGIN
EXECUTE IMMEDIATE 'CREATE TABLE ' || destination || ' AS SELECT * FROM ' ||
source;
END;
/

BD et programmation TD n 4

5/3

BEGIN
FOR t IN liste LOOP
EXECUTE IMMEDIATE 'SELECT COUNT(DISTINCT ' || t.COLUMN_NAME || ')
FROM ' || t.TABLE_NAME INTO c;
DBMS_OUTPUT.PUT_LINE(t.TABLE_NAME || ' : ' || t.COLUMN_NAME || ' (' ||
t.DATA_TYPE || ') - ' || c || ' valeurs distinctes');
END LOOP;
END;
/

BD et programmation TD n 4

6/3

Das könnte Ihnen auch gefallen