Sunteți pe pagina 1din 4

pourra la rduire la table COMMANDE lunique attribut QUANTITE.

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

Exemple :

Exercice 1
1. Sous SQL, crer une table nomme TEST_DBL contenant un seul attribut numrique. Ne pas
spcifier de cl primaire. Peupler cette table en incluant des doublons et des triplets.
2. crire un bloc PL/SQL anonyme permettant dafficher les valeurs prsentes au moins en double
dans la table TEST_DBL.

Exercice 2
On souhaite appliquer une rgle dchantillonnage la table DARMONT.EMP (Empno, Ename).
crire un programme PL/SQL (bloc PL/SQL anonyme) permettant de lire la table EMP et
dafficher les noms des employs dont les rangs dapparition dans la table sont : 1, 3, 6, 10, 15

1
2
3
4
5

La table COMMANDE contient moins de deux commandes values.

Crer la table COMMANDE et la remplir laide de SQL.


Crer un curseur contenant les quantits des commandes values.
laide dun parcours de curseur personnalis, lire la premire quantit puis, pour toutes les
quantits suivantes, cumuler la valeur absolue de quantit courante quantit prcdente
(fonction ABS).

Exercice 4 : Application

Pour dfinir ce programme, suivre les tapes suivantes.

Rsultat attendu :

1) laide du langage SQL, recopier les relations ETUDIANT, NOTATION et MATIERE de


lutilisateur DARMONT sur votre propre compte. Utiliser la commande DESC pour en
consulter le schma.

1 : SMITH
3 : WARD
6 : BLAKE
10 : TURNER

2) Dfinir en SQL la structure des relations RESULTAT et CLASSEMENT :

Indication : Utiliser un parcours personnalis de curseur dans lequel n-1 n-uplets sont lus avant
dafficher un nom demploy (n = 1, 2, 3 ; cest le nombre en italiques dans la rgle de calcul des
rangs).

la relation RESULTAT a pour attributs un numro dtudiant, un nom dtudiant, un


code matire, ainsi quun attribut note globale pour cet tudiant ;

la relation CLASSEMENT a pour attributs un numro dtudiant, un nom dtudiant,


une moyenne gnrale et un rang (place au classement).

Ne pas inclure de contrainte dintgrit dans la dfinition de ces deux relations, qui sont
temporaires et ne servent quau stockage des rsultats.

Exercice 3
Pour tenter dtablir une corrlation, on souhaite connatre la diffrence de quantit moyenne entre
les commandes successivement enregistres dans la table COMMANDE dune base de donnes
CLIENT-COMMANDE-PRODUIT. La table COMMANDE est remplie de commandes values
(cest--dire, pour lesquelles lattribut QUANTITE nest pas NULL) ou non. Les commandes non
values ne sont pas prendre en compte. crire un programme PL/SQL (bloc PL/SQL anonyme)
permettant de calculer la diffrence de quantit moyenne entre les commandes. Pour simplifier, on
BD et programmation TD n 2

On souhaite grer les rsultats dexamens de la Facult de Sciences conomiques et de Gestion. Il


sagit de dfinir un programme PL/SQL permettant linsertion automatique dinformations dans les
relations rsultats RESULTAT et CLASSEMENT, partir des donnes des relations
sources ETUDIANT, NOTATION et MATIERE, qui contiennent respectivement des
renseignements sur les tudiants, les notes obtenues par les tudiants et les coefficients affects aux
matires.

Rgle de calcul des rangs successifs :


+
+
+
+
+

Cas particuliers traiter :

4. Est-il possible dajouter une cl primaire la table TEST_DBL depuis un bloc PL/SQL ?

= 0
= 1
= 3
= 6
= 10

Rsultat attendu = ( |10 5| + |8 10| + |9 8| + |13 9| ) / 4 = 3

Indications :

3. Intgrer dans le programme PL/SQL la suppression les doublons.

1
3
6
10
15

QUANTITE
5
NULL
10
8
9
13

1/5

3) Dfinir un bloc PL/SQL anonyme permettant dinsrer dans RESULTAT tous les n-uplets
constitus du numro dun tudiant, de son nom, du code dune matire et de la note obtenue
par cet tudiant dans cette matire. Le calcul de cette note doit tenir compte des coefficients
de contrle continu et dexamen dfinis pour la matire en question, ainsi que de la
possibilit davoir des valeurs nulles pour les notes des tudiants, qui sont alors assimiles
BD et programmation TD n 2

2/5

0 (utiliser la fonction NVL). Les n-uplets considrs doivent tre extraits des tables
ETUDIANT, NOTATION et MATIERE de manire itrative, grce un curseur adapt.
4) Terminer le traitement en ralisant linsertion dans la relation CLASSEMENT des n-uplets
constitus du numro dun tudiant, de son nom, de son prnom, de la moyenne gnrale
obtenue dans toutes les matires par cet tudiant (ces informations doivent tre extraites de
la table RESULTAT) et de son rang (place), qui doit tre calcul. Pour simplifier, on
considre que toutes les matires sont quivalentes en termes de notes. Utiliser un curseur
dans lequel les enregistrements sont tris.
Questions complmentaires
Modifier le programme afin de prendre en compte :

le cas o plusieurs tudiants ont le mme rang (ex quo) ;

le cas dtudiants nayant aucune note (par dfaut, leur moyenne gnrale est 0) ;

la possibilit de navoir aucun n-uplet dans la relation ETUDIANT. Dans ce cas, un n-uplet de
valeur (0, Aucun tudiant, NULL, NULL) doit tre insr dans la relation RESULTAT et le
traitement doit sarrter.

Correction
-- Ex. 1
DECLARE
CURSOR doublons IS SELECT dbl FROM test_dbl
GROUP BY dbl
HAVING COUNT(*)>1;
nuplet doublons%ROWTYPE;
BEGIN
DBMS_OUTPUT.PUT_LINE('Valeurs en double dans TEST_DBL :');
FOR nuplet IN doublons LOOP
DBMS_OUTPUT.PUT_LINE(nuplet.dbl);
DELETE FROM test_dbl WHERE dbl=nuplet.dbl;
INSERT INTO test_dbl VALUES (nuplet.dbl);
END LOOP;
DBMS_OUTPUT.PUT_LINE('Doublons supprims !');
--ALTER TABLE test_dbl ADD CONSTRAINT test_dbl_pri PRIMARY KEY(dbl);
--Ne fonctionne pas
END;
/

-- Ex. 2
DECLARE
CURSOR employes IS select ename from darmont.emp;
e employes%ROWTYPE;
i INTEGER;
n INTEGER := 1;
BEGIN
OPEN employes;
FETCH employes INTO e; -- 1er n-uplet
WHILE employes%FOUND LOOP
-- Lecture de n-1 n-uplets supplmentaires (on saute des lignes)
i := 1;
WHILE (i < n) AND (employes%FOUND) LOOP
FETCH employes INTO e;
i := i + 1;
END LOOP;
-- Affichage
IF employes%FOUND THEN -- Si on nest pas en fin de curseur
DBMS_OUTPUT.PUT_LINE(employes%ROWCOUNT || ' : ' || e.ename);
n := n + 1;
FETCH employes INTO e; -- N-uplet suivant
END IF;
END LOOP;
CLOSE employes;
END;
/

BD et programmation TD n 2

3/5

BD et programmation TD n 2

4/5

-- Ex. 3

-- Edition des resultats et classement des etudiants (bloc PL/SQL)

DECLARE
CURSOR valuees IS
SELECT quantite FROM commande WHERE quantite IS NOT NULL;
cde valuees%ROWTYPE;
prec REAL; -- quantite precedente
cour REAL; -- quantite courante
cumul REAL;
moyenne REAL;
ncv INTEGER;
pas_assez EXCEPTION;

DECLARE
-- Calcul de la note globale par matiere
CURSOR etudiant_note IS
SELECT ETUDIANT.nume, nom, MATIERE.codemat,
((NVL(notecc, 0) * coefcc) + (NVL(notexam, 0) *coefexam)) /
(coefcc + coefexam) AS note
FROM ETUDIANT, NOTATION, MATIERE
WHERE ETUDIANT.nume = NOTATION.nume
AND NOTATION.codemat = MATIERE.codemat;
en etudiant_note%ROWTYPE;
nbe INTEGER;
-- Nombre d'etudiants a classer
rg INTEGER;
-- Place dans le classement general
moy NUMBER(5,2); -- Moyenne generale d'un etudiant
aucun_etudiant EXCEPTION;

BEGIN
-- Test nombre de commandes valuees
SELECT COUNT(*) INTO ncv FROM commande WHERE quantite IS NOT NULL;
IF ncv < 2 THEN
RAISE pas_assez;
END IF;

-- Calcul de la moyenne generale


-- Le tri permet de faciliter le traitement ulterieur du classement.
CURSOR etudiant_classe IS
SELECT nume, nom, AVG(note) moyenne
FROM RESULTAT
GROUP BY nume, nom
ORDER BY moyenne DESC;
ec etudiant_classe%ROWTYPE;

-- Acces 1er n-uplet


OPEN valuees;
FETCH valuees INTO cde; -- 1er n-uplet
prec := cde.quantite; -- Initialisation du prcdent
-- Acces aux suivants et cumul
cumul:=0;
WHILE valuees%FOUND LOOP
cour := cde.quantite;
cumul := cumul + ABS(cour - prec);
prec := cour;
FETCH valuees INTO cde; -- N-uplet uivant
END LOOP;
CLOSE valuees;

-- Gestion des etudiants sans aucune note


CURSOR etudiant_non_note IS
SELECT nume, nom FROM ETUDIANT
WHERE nume NOT IN (SELECT DISTINCT nume FROM NOTATION);
enn etudiant_non_note%ROWTYPE;
BEGIN
-- Destruction des donnees eventuelles des annees precedentes
DELETE FROM RESULTAT;
DELETE FROM CLASSEMENT;

-- Calcul et affichage de la moyenne


moyenne := cumul / (ncv - 1);
DBMS_OUTPUT.PUT_LINE('Moyenne = '||TO_CHAR(moyenne));

-- Test de l'existance de n-uplets dans la relation ETUDIANT


SELECT COUNT(*) INTO nbe FROM ETUDIANT;
IF nbe=0 THEN
RAISE aucun_etudiant;
END IF;

EXCEPTION
WHEN pas_assez THEN
RAISE_APPLICATION_ERROR(-20501,'Pas assez de commandes');
END;
/

-- Insertion des etudiants notes comme n-uplets dans RESULTAT


FOR en IN etudiant_note LOOP
INSERT INTO RESULTAT
VALUES (en.nume, en.nom, en.codemat, en.note);
END LOOP;

-- Ex. 4
-- RESULTAT

-- Insertion des etudiants sans note comme n-uplets dans RESULTAT


FOR enn IN etudiant_non_note LOOP
INSERT INTO RESULTAT
VALUES (enn.nume, enn.nom, NULL, 0);
END LOOP;

create table resultat(


nume number(2),
nom char(20),
codemat number(2),
note number(5,2));
-- CLASSEMENT

-- Initialisation des variables locales


moy:=21;
rg:=-1;

create table classement(


nume number(2),
nom char(20),
moyenne number(5,2),
rang number(2));

-- Insertion des n-uplets dans la relation CLASSEMENT


FOR ec IN etudiant_classe LOOP
IF moy>ec.moyenne THEN
rg:=etudiant_classe%ROWCOUNT;
END IF;

BD et programmation TD n 2

5/5

BD et programmation TD n 2

6/5

INSERT INTO CLASSEMENT


VALUES (ec.nume, ec.nom, ec.moyenne, rg);
moy:=ec.moyenne;
END LOOP;
-- Validation de la transaction
COMMIT;
EXCEPTION
WHEN aucun_etudiant THEN
INSERT INTO RESULTAT
VALUES(0, 'Aucun etudiant', NULL, NULL);
END;
/

BD et programmation TD n 2

7/5

S-ar putea să vă placă și