TD 3 corrigé

Transcription

TD 3 corrigé
Exercice 3 : Enregistrements
Université Lumière – Lyon 2, Faculté de Sciences Économiques et de Gestion
Master d’Informatique M2 spécialité IUP IDS – Année 2005-2006
Bases de données et programmation – TD n° 3
J. Darmont (http://eric.univ-lyon2.fr/~jdarmont/), 25/10/05
1. Nous allons réutiliser la relation PILOTE du TD n° 1. Si ce n’est pas déjà fait, recopier la table
PILOTE de l’utilisateur DARMONT sur votre compte.
1. Dans un bloc PL/SQL anonyme, définir un type collection de réels VARRAY de taille 10 qui
contiendra des notes d’examen.
2. Dans un bloc PL/SQL anonyme, définir un type enregistrement composé des champs suivants :
• nom, du même type que l’attribut PLNOM de PILOTE ;
• prénom, du même type que l’attribut PLPRENOM de PILOTE ;
• ville, du même type que l’attribut VILLE de PILOTE ;
• salaire, du même type que l’attribut SALAIRE de PILOTE.
2. Dans la section déclaration, définir une variable de ce type et l’initialiser avec trois notes.
2. Définir une variable de ce type.
3. Dans la section de code, terminer l’initialisation avec les 7 notes manquantes. Tester.
3. Dans la section de code, définir une requête paramétrée (en utilisant le caractère &) permettant de
lire le nom, le prénom, la ville et le salaire d’un pilote de la dont le numéro de pilote est saisi au
clavier et de le stocker dans la variable enregistrement préalablement définie. Afficher le résultat au
format suivant : Prénom NOM (Ville) : Salaire.
Exercice 1 : Collections VARRAY
4. Calculer et afficher la moyenne des notes.
5. Ajouter encore une note dans la collection. Que se passe-t-il ?
6. Afficher la taille maxi et la taille réelle du tableau.
Exercice 4 : Sous-programmes et collections
7. À l’aide de la méthode trim, effacer une note du tableau, puis afficher de nouveau la taille maxi
et la taille réelle du tableau.
1. Dans un bloc PL/SQL anonyme, définir une fonction de nom « MonMax » prenant en paramètres
d’entrée deux réels et renvoyant un réel égal au plus grand des deux paramètres.
8. À l’aide de la méthode delete, effacer le tableau, puis afficher de nouveau la taille maxi et la
taille réelle du tableau.
2. Dans le programme principal, déclarer deux variables réelles « a » et « b » et leur affecter une
valeur. Appeler la fonction « MonMax » pour « a » et « b » et afficher le résultat.
Exercice 2 : Collections TABLE
3. Dans le même bloc PL/SQL, définir un type collection de réels TABLE nommé « TabReels »,
ainsi qu’une variable « tab » de ce type. Initialiser cette variable avec plusieurs valeurs.
1. Dans un bloc PL/SQL anonyme, définir un type collection de réels TABLE qui contiendra les
notes de contrôle continu stockées dans la relation NOTATION du TD n° 2.
2. Définir une variable de ce type l’initialiser à vide.
4. Définir une fonction de nom « MultiMax » prenant en paramètre d’entrée un « TabReels » et
renvoyant le plus grand nombre contenu dans ce tableau. Faire appel à la fonction « MonMax »
pour effectuer le traitement. Dans le programme principal, appeler la fonction « MultiMax » pour
« tab » et afficher le résultat.
3. Dans la section de code, charger en mémoire dans la collection les notes de contrôle continu
contenues dans la relation NOTATION à l’aide d’un curseur. Afficher les notes au fur et à mesure.
Tester. Ce traitement aurait-il été possible avec un VARRAY ?
5. Ajouter à la fonction « MultiMax » un traitement d’exception déclenchant une erreur fatale
lorsque la table passée en paramètre est vide. Tester en initialisant « tab » à vide.
4. Calculer et afficher la moyenne des notes contenues dans la collection.
6. Toujours dans le même bloc PL/SQL, définir une procédure de nom « Tri » permettant de trier
par ordre croissant le contenu d’un « TabReels » passé en paramètre. On pourra programmer un
simple tri par permutation.
5. Vérifier que votre calcul est bon en affichant le résultat d’une requête SQL utilisant la fonction
d’agrégat AVG().
7. Écrire une procédure de nom « Affiche » permettant d’afficher le contenu d’un « TabReels ».
6. Afficher à l’écran l’indice du premier élément de la collection, l’indice du dernier élément et le
nombre d’éléments dans la collection.
8. Dans le programme principal, faire appel aux procédures « Tri » et « Affiche » pour « tab ». Quel
doit être le mode de passage de ce paramètre dans caque cas ?
7. Supprimer les éléments d’indice 1, 10 et 16, puis répéter la question 6 (copier/coller).
8. Afficher tous les éléments de la collection.
BD et programmation – TD n° 3
1/3
BD et programmation – TD n° 3
2/3
Questions complémentaires :
Correction
9. Toujours dans le même bloc PL/SQL, définir une procédure de nom « Tri_conserve » prenant en
entrée un « TabReels » non trié et fournissant en sortie un « TabReels » trié. Le « TabReels » en
entrée doit conserver son ordre d’éléments initial (c’est-à-dire, ne pas être modifié en sortie). Faire
appel à la procédure « Tri » pour effectuer le traitement.
10. Dans le programme principal, déclarer une seconde variable « tab_tri » de type « TabReels » et
l’initialiser à vide. Mettre en commentaire l’appel aux procédures « Tri » et « Affiche » des
questions 6 et 7 et faire appel à la procédure « Tri_conserve » pour « tab » et « tab_tri », puis à la
procédure « Affiche » deux fois pour « tab », puis « tab_tri ».
-- Ex. 1 : VARRAY
DECLARE
TYPE TabReels IS VARRAY(10) OF REAL;
notes TabReels := TabReels(10.5, 15, 13);
i INTEGER;
m REAL := 0;
BEGIN
notes.EXTEND(7);
notes(4) := 8.5;
notes(5) := 18.5;
notes(6) := 16;
notes(7) := 4;
notes(8) := 9.5;
notes(9) := 12;
notes(10) := 11;
FOR i IN 1..notes.COUNT LOOP
m := m + notes(i);
END LOOP;
m := m / notes.COUNT;
DBMS_OUTPUT.PUT_LINE('Moyenne = '||TO_CHAR(m));
-- notes.EXTEND; NE FONCTIONNE PLUS (taille maxi = 10)
-- notes(11) := 20;
DBMS_OUTPUT.PUT_LINE('Taille actuelle / Taille limite = '
||notes.COUNT||' / '||notes.LIMIT);
notes.TRIM;
DBMS_OUTPUT.PUT_LINE('Taille actuelle / Taille limite = '
||notes.COUNT||' / '||notes.LIMIT);
notes.DELETE;
DBMS_OUTPUT.PUT_LINE('Taille actuelle / Taille limite = '
||notes.COUNT||' / '||notes.LIMIT);
END;
/
-- Ex. 2 : TABLE
DECLARE
TYPE TabReels IS TABLE OF REAL;
notes TabReels := TabReels();
CURSOR notes_stockees IS SELECT notecc FROM notation
WHERE notecc IS NOT NULL;
t notes_stockees%ROWTYPE;
i INTEGER;
m REAL := 0;
BEGIN
FOR t IN notes_stockees LOOP
notes.EXTEND;
notes(notes.COUNT) := t.notecc;
DBMS_OUTPUT.PUT_LINE('notes('||notes.count||') = '||t.notecc);
END LOOP;
BD et programmation – TD n° 3
3/3
BD et programmation – TD n° 3
4/3
FOR i IN 1..notes.COUNT LOOP
m := m + notes(i);
END LOOP;
m := m / notes.COUNT;
DBMS_OUTPUT.PUT_LINE('Moyenne = '||m);
-- Fonction max entre deux nombres
FUNCTION MonMax(a IN REAL, b IN REAL) RETURN REAL IS
BEGIN
IF a > b THEN
RETURN a;
ELSE
RETURN b;
END IF;
END;
SELECT AVG(notecc) INTO m FROM notation;
DBMS_OUTPUT.PUT_LINE('AVG(notecc) = '||m);
DBMS_OUTPUT.PUT_LINE('Indice premier : '||notes.FIRST);
DBMS_OUTPUT.PUT_LINE('Indice dernier : '||notes.LAST);
DBMS_OUTPUT.PUT_LINE('Nombre elements : '||notes.COUNT);
-- Fonction max dans un tableau
notes.delete(1);
notes.delete(10);
notes.delete(16);
DBMS_OUTPUT.PUT_LINE('Indice premier : '||notes.FIRST);
DBMS_OUTPUT.PUT_LINE('Indice dernier : '||notes.LAST);
DBMS_OUTPUT.PUT_LINE('Nombre elements : '||notes.COUNT);
FUNCTION MultiMax(t IN TabReels) RETURN REAL IS
-- Déclarations locales
i INTEGER;
m REAL;
vide EXCEPTION;
i := notes.FIRST;
WHILE i<=notes.LAST LOOP
DBMS_OUTPUT.PUT_LINE('notes('||i||') = '||notes(i));
i := notes.NEXT(i);
END LOOP;
BEGIN
IF t.COUNT = 0 THEN
RAISE vide;
END IF;
m := t(1);
FOR i IN 2..t.COUNT LOOP
m := MonMax(m, t(i));
END LOOP;
RETURN m;
END;
/
-- Ex. 3 : RECORD
DECLARE
TYPE Personne IS RECORD(
nom pilote.plnom%TYPE,
prenom pilote.plprenom%TYPE,
ville pilote.ville%TYPE,
salaire pilote.salaire%TYPE);
pl Personne;
EXCEPTION
WHEN vide THEN RAISE_APPLICATION_ERROR(-20500,
'MultiMax error : table vide');
END;
-- Procédure tri d'un tableau
BEGIN
SELECT plnom, plprenom, ville, salaire
INTO pl
FROM pilote
WHERE plnum = &Numéro_de_pilote;
PROCEDURE Tri(t IN OUT TabReels) IS
-- Déclarations locales
i INTEGER;
j INTEGER;
temp REAL;
DBMS_OUTPUT.PUT_LINE(pl.prenom||' '||UPPER(pl.nom)||' ('||pl.ville||') : '
||pl.salaire);
END;
/
BEGIN
FOR i IN 1..t.COUNT-1 LOOP
FOR j IN i+1..t.COUNT LOOP
IF t(j) < t(i) THEN
temp := t(i);
t(i) := t(j);
t(j) := temp;
END IF;
END LOOP;
END LOOP;
-- Ex. 4 : SOUS-PROGRAMMES ET COLLECTIONS
DECLARE
-- Déclarations du programme principal
a REAL := 4.5;
b REAL := 3.14;
END;
TYPE TabReels IS TABLE OF REAL;
tab TabReels := TabReels(-3.25, 6.5, 10.2, 9.55, 15.2, 0.255);
tab_tri TabReels := TabReels();
BD et programmation – TD n° 3
5/3
BD et programmation – TD n° 3
6/3
-- Procédure tri sans perdre l’ordre initial
PROCEDURE Tri_conserve(t_in IN TabReels, t_out OUT TabReels) IS
BEGIN
t_out := t_in;
Tri(t_out);
END;
-- Procédure affichage d’un tableau
PROCEDURE Affiche(t IN TabReels, etiquette VARCHAR) IS
-- Déclarations locales
i INTEGER;
chaine VARCHAR(255) := '';
BEGIN
FOR i IN 1..t.COUNT LOOP
chaine := chaine || ' ' || t(i);
END LOOP;
DBMS_OUTPUT.PUT_LINE(etiquette || ' =' || chaine);
END;
-- Programme principal
BEGIN
DBMS_OUTPUT.PUT_LINE('MonMax(' || a || ' ; ' || b || ') = ' ||
MonMax(a,b));
DBMS_OUTPUT.PUT_LINE('MultiMax = ' || MultiMax(tab));
---
Tri(tab);
Affiche(tab, 'Tableau trié');
Tri_conserve(tab, tab_tri);
Affiche(tab, 'Tableau non trié');
Affiche(tab_tri, 'Tableau trié');
END;
/
BD et programmation – TD n° 3
7/3