You are on page 1of 3

BD et programmation TD n 5 1/2

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 5
J . Darmont (http://eric.univ-lyon2.fr/~jdarmont/), 15/11/05


Exercice 1 : Curseur dynamique

Dans un bloc PL/SQL anonyme, dfinir une variable chane de caractres nomme NomTable et
lui affecter le nomdune table de votre compte. crire le code PL/SQL permettant dafficher le
schma de cette table (la liste de ses attributs) au format NOM_TABLE ( ATT1, ATT2) . Les attributs
de vos tables sont rpertoris dans la vue systme USER_TAB_COLUMNS ( TABLE_NAME,
COLUMN_NAME, ) .


Exercice 2 : Curseur simple et curseur dynamique imbriqus

1. Modifier le bloc PL/SQL de lexercice 1 de manire afficher le schma de toutes les tables et
vues prsentes dans votre catalogue systme (vue TAB ( TNAME, ) ).

2. Ajouter la description du schma de chaque table son nombre de n-uplets. Dans le cas o la
table est vide (zro n-uplet), on affichera de prfrence la chane Vide .

3. Transformer le bloc PL/SQL anonyme en procdure stocke nomme schema . Comment
gnraliseriez-vous cette procdure tout utilisateur ?


Exercice 3 : Curseurs dynamiques

crire un bloc PL/SQL anonyme permettant dafficher toutes les valeurs distinctes possibles du
premier attribut de la premire table de votre catalogue systme. Grer le cas o aucune table nest
prsente comme une exception.


Exercice 4 : Contraintes de domaine et contraintes dynamiques dans un dclencheur

Soit le schma relationnel dune agence bancaire rgionale.

CLIENT (NumCl, Nom, Prenom, Adr, CP, Ville, Salaire, NumConjoint#)
DETENTEUR (NumCl#, NumCpt#)
COMPTE (NumCpt, DateOuvr, Solde)

Cls primaires
Cls trangres#

NumCl et NumConjoint sont dfinis sur le mme domaine.

On souhaite mettre en uvre un dclencheur avant insertion ou mise jour permettant de contrler
les contraintes suivantes :
le dpartement dans lequel habite le client doit tre 01, 07, 26, 38, 42, 69, 73, ou 74 (rgion
Rhne-Alpes) ;
le nomdu conjoint doit tre le mme que celui du client.
BD et programmation TD n 5 2/2
1. laide du langage SQL, crer la structure simplifie de la table CLIENT (NumCl, Nom, CP,
NumConjoint#).

2. crire le code du dclencheur, puis le crer.

Rappel : Dfinition dun dclencheur

CREATE [ OR REPLACE] TRI GGER Nom_Dcl encheur
BEFORE | AFTER
I NSERT | DELETE | UPDATE / [ I NSERT] [ [ OR] DELETE] [ [ OR] UPDATE]
ON Nom_Tabl e
[ FOR EACH ROW]
- - Bl oc PL/ SQL cont enant l e t r ai t ement ef f ect uer

3. Excuter le dclencheur plusieurs fois en insrant des n-uplets dans la table CLIENT.

4. Vrifier son bon fonctionnement en affichant le contenu de la table CLIENT.


Exercice 5 : Numrotation automatique de cl primaire laide dun dclencheur

Soit une table quelconque TABL, dont la cl primaire CLENUM est numrique. Dfinir un
dclencheur avant insertion permettant dimplmenter une numrotation automatique de la cl. Le
premier numro doit tre 1.

1. Crer laide de SQL la structure de la table TABL (Clenum).

2. Saisir le code du dclencheur adquat dans un fichier, puis le crer.

3. Excuter le dclencheur plusieurs fois en insrant des n-uplets dans la table TABL, puis
supprimer un n-uplet et en insrer un dernier.

4. Vrifier son bon fonctionnement en affichant le contenu de la table TABL.


Exercice 6 complmentaire : Application des curseurs dynamiques Le grand nettoyage

crire un bloc PL/SQL permettant de dtruire toutes les tables et les vues de votre compte. Pour
viter toute erreur lexcution, tenir compte des contraintes de cl trangre en les dtruisant au
pralable. Ces dernires sont listes dans la table systme USER_CONSTRAI NTS( TABLE_NAME,
CONSTRAI NT_NAME, ) .

BD et programmation TD n 5 3/2
Correction


-- Ex. 1

DECLARE
TYPE DynCur sor I S REF CURSOR;
nomt abl e VARCHAR( 50) : = ' EMP' ;
dyn DynCur sor ;
at t r i but VARCHAR( 50) ;
schema VARCHAR( 500) ;

BEGI N
schema : = nomt abl e | | ' ( ' ;
OPEN dyn FOR ' SELECT COLUMN_NAME FROM USER_TAB_COLUMNS
WHERE TABLE_NAME=' ' ' | | nomt abl e | | ' ' ' ' ;
FETCH dyn I NTO at t r i but ;
WHI LE dyn%FOUND LOOP
I F dyn%ROWCOUNT > 1 THEN
schema : = schema | | ' , ' ;
END I F;
schema : = schema | | at t r i but ;
FETCH dyn I NTO at t r i but ;
END LOOP;
CLOSE dyn;
schema : = schema | | ' ) ' ;
DBMS_OUTPUT. PUT_LI NE( schema) ;
END;
/


-- Ex. 2

CREATE OR REPLACE PROCEDURE schema I S

TYPE DynCur sor I S REF CURSOR;
CURSOR t abl es I S SELECT TNAME FROM TAB ORDER BY TNAME;
t t abl es%ROWTYPE;
dyn DynCur sor ;
at t r i but VARCHAR( 50) ;
schema VARCHAR( 500) ;
c I NTEGER;

BEGI N
FOR t I N t abl es LOOP
schema : = t . TNAME | | ' ( ' ;
OPEN dyn FOR ' SELECT COLUMN_NAME FROM USER_TAB_COLUMNS
WHERE TABLE_NAME=' ' ' | | t . TNAME | | ' ' ' ' ;
FETCH dyn I NTO at t r i but ;
WHI LE dyn%FOUND LOOP
I F dyn%ROWCOUNT > 1 THEN
schema : = schema | | ' , ' ;
END I F;
schema : = schema | | at t r i but ;
FETCH dyn I NTO at t r i but ;
END LOOP;
CLOSE dyn;
schema : = schema | | ' ) - ' ;
EXECUTE I MMEDI ATE ' SELECT COUNT( *) FROM ' | | t . TNAME I NTO c;
BD et programmation TD n 5 4/2
I F c>0 THEN
schema : = schema | | c | | ' n- upl et ( s) ' ;
ELSE
schema : = schema | | ' Vi de' ;
END I F;
DBMS_OUTPUT. PUT_LI NE( schema) ;
END LOOP;
END;
/

- - Pr endr e l e nomd ut i l i sat eur en par amt r e
- - Al l er cher cher l e nomdes at t r i but s dans ALL_TAB_COLUMNS pour l USER concer n
- - Compt er l es n- upl et s des t abl es USER. nom_t abl e


-- Ex. 3

DECLARE
cpt I NTEGER;
r i en EXCEPTI ON;
CURSOR l i st e_t ab I S SELECT TNAME FROM TAB;
nomt abl e VARCHAR( 255) ;
r q VARCHAR( 255) ;
TYPE Pt r Cur seur I S REF CURSOR;
l i st e Pt r Cur seur ;
nomat t VARCHAR( 255) ;
val VARCHAR( 255) ;

BEGI N
- - Test d' exi st ence des t abl es
SELECT COUNT( *) I NTO cpt FROM TAB;
I F CPT = 0 THEN
RAI SE r i en;
END I F;

- - Recuper at i on du nomde l a pr emi er e t abl e
OPEN l i st e_t ab;
FETCH l i st e_t ab I NTO nomt abl e;
CLOSE l i st e_t ab;
DBMS_OUTPUT. PUT_LI NE( ' 1r e t abl e : ' | | nomt abl e) ;

- - Recuper at i on du nomdu pr emi er at t r i but de l a t abl e
r q : = ' SELECT COLUMN_NAME FROM USER_TAB_COLUMNS WHERE
TABLE_NAME=' ' ' | | nomt abl e | | ' ' ' ' ;
OPEN l i st e FOR r q;
FETCH l i st e I NTO nomat t ; - - 1er e val eur
CLOSE l i st e;
DBMS_OUTPUT. PUT_LI NE( ' 1er at t r i but : ' | | nomat t ) ;

- - Recuper at i on des val eur de l ' at t r i but + af f i chage
r q : = ' SELECT DI STI NCT ' | | nomat t | | ' FROM ' | | nomt abl e;
OPEN l i st e FOR r q;
FETCH l i st e I NTO val ;
WHI LE l i st e%FOUND LOOP
DBMS_OUTPUT. PUT_LI NE( val ) ;
FETCH l i st e I NTO val ;
END LOOP;
CLOSE l i st e;

EXCEPTI ON
WHEN r i en THEN RAI SE_APPLI CATI ON_ERROR( - 20501, ' Aucune t abl e dans l a base' ) ;

END;
/
BD et programmation TD n 5 5/2
-- Ex. 4

CREATE OR REPLACE TRI GGER I NS_UPDT_CLI ENT
BEFORE I NSERT OR UPDATE ON CLI ENT
FOR EACH ROW

DECLARE

nom_conj oi nt CLI ENT. NOM%TYPE;
compt eur CLI ENT. NUMCL%TYPE;
pb_dept EXCEPTI ON;
pb_conj oi nt 1 EXCEPTI ON;
pb_conj oi nt 2 EXCEPTI ON;

BEGI N

- - Cont r ai nt e sur l e dpar t ement

I F TRUNC( : NEW. CP/ 1000) NOT I N ( 01, 07, 26, 38, 42, 69, 73, 74) THEN
RAI SE pb_dept ;
END I F;

- - Cont r ai nt e sur l e nomdu conj oi nt ( + t est d exi st ence du conj oi nt )

I F : NEW. NUMCONJ OI NT I S NOT NULL THEN

- - Test d' exi st ence
SELECT COUNT( *)
I NTO compt eur
FROM CLI ENT
WHERE NUMCL = : NEW. NUMCONJ OI NT;
I F compt eur = 0 THEN - - Pas de conj oi nt
RAI SE pb_conj oi nt 1 ;
END I F;

- - Test sur l e nom
SELECT NOM
I NTO nom_conj oi nt
FROM CLI ENT
WHERE NUMCL = : NEW. NUMCONJ OI NT;
I F nom_conj oi nt <> : NEW. NOM THEN
RAI SE pb_conj oi nt 2;
END I F;

END I F;

EXCEPTI ON

WHEN pb_dept THEN RAI SE_APPLI CATI ON_ERROR ( - 20501,
' Mi se j our i mpossi bl e : l e cl i ent n' ' habi t e pas en r gi on
Rhne- Al pes ! ' ) ;

WHEN pb_conj oi nt 1 THEN RAI SE_APPLI CATI ON_ERROR ( - 20502,
' Mi se j our i mpossi bl e : l e conj oi nt du cl i ent n' ' exi st e pas ! ' ) ;

WHEN pb_conj oi nt 2 THEN RAI SE_APPLI CATI ON_ERROR ( - 20503,
' Mi se j our i mpossi bl e : l e nomdu conj oi nt est di f f r ent de cel ui du
cl i ent ! ' ) ;

END;
/
BD et programmation TD n 5 6/2
-- Ex. 5

CREATE OR REPLACE TRI GGER cl eaut o BEFORE I NSERT ON t abl FOR EACH ROW

DECLARE
n I NTEGER;
maxcl e I NTEGER;

BEGI N
- - Recher che s' i l exi st e des n- upl et s dans l a t abl e
SELECT COUNT( *) I NTO n FROM t abl ;
I F n > 0 THEN
- - Recher che l a val eur de cl e C l a pl us el evee
- - et af f ect e C+1 a l a nouvel l e cl e
SELECT MAX( cl enum) I NTO maxcl e FROM t abl ;
: new. cl enum: = maxcl e + 1;
ELSE
- - Pr emi r e i nser t i on
: new. cl enum: = 1;
END I F;

END;
/


-- Ex. 6

DECLARE
r q VARCHAR( 255) ;
CURSOR ct r t I S SELECT CONSTRAI NT_NAME, TABLE_NAME FROM USER_CONSTRAI NTS
WHERE CONSTRAI NT_TYPE = ' R' ;
c ct r t %ROWTYPE;
CURSOR t bl I S SELECT TNAME, TABTYPE FROM TAB;
t t bl %ROWTYPE;

BEGI N
- - Dest r uct i on des cont r ai nt es de cl e et r anger e
FOR c I N ct r t LOOP
r q : = ' ALTER TABLE ' | | c. TABLE_NAME | | ' DROP CONSTRAI NT ' | |
c. CONSTRAI NT_NAME;
EXECUTE I MMEDI ATE r q;
DBMS_OUTPUT. PUT_LI NE( ' Dest r uct i on de l a cont r ai nt e ' | |
c. CONSTRAI NT_NAME | | ' dans l a t abl e ' | | c. TABLE_NAME) ;
END LOOP;

- - Dest r uct i on des t abl es
FOR t I N t bl LOOP
r q : = ' DROP ' | | t . TABTYPE | | ' ' | | t . TNAME;
EXECUTE I MMEDI ATE r q;
DBMS_OUTPUT. PUT_LI NE( ' Dest r uct i on de l a ' | | t . TABTYPE | | ' ' | |
t . TNAME) ;
END LOOP;

END;
/

You might also like