Exam Maitrise CMO partie BDO O2 janvier 2002

Transcription

Exam Maitrise CMO partie BDO O2 janvier 2002
Nom :
Prénom :
page 1
Module Bases de Données et Web
Examen du 24 janvier 2008
Version CORRIGEE
Les documents sont autorisés – Durée : 2h.
Répondre aux questions sur la feuille du sujet dans les cadres appropriés. La taille des cadres suggère celle de la réponse
attendue. Utiliser le dos de la feuille précédente si la réponse déborde du cadre. Le barème est donné à titre indicatif. La qualité
de la rédaction sera prise en compte. Ecrire à l’encre bleue ou noire. Ne pas dégrafer le sujet.
Exercice 1. Objet relationnel et SQL3
6 pts
On donne ci-dessous le schéma SQL3 d'une base de données concernant des équipes, des joueurs et des
fans :
create type Joueur as object (
nom varchar2(30),
age number(2)
);
/
create type Ens_Joueurs as table of ref Joueur;
/
create type Ens_Couleurs as table of varchar2(30);
/
create type Equipe as object (
nom varchar2(30),
joueurs Ens_Joueurs,
capitaine ref Joueur,
couleurs Ens_Couleurs);
/
create type Ens_Equipes as table of ref Equipe;
/
create type Fan as object (
nom varchar2(30),
joueurs_favoris Ens_Joueurs,
equipes_favorites Ens_Equipes,
couleur varchar2(30));
/
create table LesEquipes of Equipe
nested table joueurs store as E1,
nested table couleurs store as E2;
create table LesJoueurs of Joueur;
create table LesFans of Fan
nested table joueurs_favoris store as J1,
nested table equipes_favorites store as J2;
On instancie le schéma en exécutant les commandes suivantes :
insert into LesJoueurs values(Joueur('Zidane', 31));
insert into LesJoueurs values(Joueur('Barthez', 32));
create or replace procedure insereEquipe is
j1 ref Joueur;
j2 ref Joueur;
Lettres initiales du Prénom et du Nom:
page 2
begin
select ref(j) into j1 from LesJoueurs j where j.nom='Zidane';
select ref(j) into j2 from LesJoueurs j where j.nom='Barthez';
insert into LesEquipes values(
Equipe('equipe de France', Ens_Joueurs(j1, j2), j1, Ens_Couleurs('bleu', 'blanc', 'rouge'))
);
end;
Question 1 : On effectue la commande ci-dessous pour insérer un nouveau joueur dans LesJoueurs.
insert into LesJoueurs values(Joueur('Henry', 33));
Ecrivez une procédure pour insérer ce nouveau joueur dans l’équipe de France.
create or replace procedure insereHenry is
j1 ref Joueur;
end;
Réponse :
create or replace procedure insereHenry is
j1 ref Joueur;
begin
Select ref(j) into j1 from LesJoueurs where j.nom =’Henry’ ;
Insert into (select e.joueurs from LesEquipes e where e.nom=’équipe de France’)
values(j1) ;
end;
Question2 : Ecrivez en SQL3 les requêtes suivantes :
R1 : pour chaque équipe ayant au moins un fan, donner le nom de l'équipe et son nombre de fans.
Réponse : select e.nom, count(*) as nombre_de_fans
from LesFans f, table (f.equipes_favorites) e
group by e.nom;
Lettres initiales du Prénom et du Nom:
page 3
R 2 : Nom des équipes dont le capitaine est le joueur le plus jeune de l’équipe
Réponse : erreur avec min ?)
select x.nom
from LesEquipes x
where x.capitaine.age = (select min(y.age) from table(x.joueurs) y);
R3 : Pour chaque équipe, donnez le nom de l’équipe et la moyenne d’âge des joueurs de l’équipe
Réponse:
Select e.nom, avg(j.age)
From LesEquipes e, table(e.joueurs) j
Group by e.nom
R4 : Nom des fans dont au moins une équipe favorite a un joueur qui n’a pas de fan.
Lettres initiales du Prénom et du Nom:
Réponse :
Select f.nom
From LesFans f, table(f.equipes_favorites) e, table(e.joueurs) j
Where j.nom not in (select jf.nom from LesFans ff, table (ff.joueurs_favoris) jf)
Question 3.
On complète la BD avec les instructions suivantes
insert into LesFans values(Fan('F1',null,null,'bleu'));
insert into LesFans values(Fan('F2',null,null,'vert'));
insert into LesFans values(Fan('F3',null,null,'bleu'));
insert into LesFans values(Fan('F1',null,null,'bleu'));
Remarque : il y a 2 fans qui ont le même nom.
Exprimer en une seule phrase les requêtes suivantes et donner le résultat de la requête.
R1 : select distinct f1.nom, f2.nom
from LesFans f1, LesFans f2
where f1.couleur = f2.couleur;
R1:
Résultat
R2 : select distinct f1.nom, f2.nom
from LesFans f1, LesFans f2
where f1.couleur =f2.couleur
and f1.nom <> f2.nom;
R2:
page 4
Lettres initiales du Prénom et du Nom:
Résultat
R3 : select distinct f1.nom, f2.nom
from LesFans f1, LesFans f2
where f1.couleur =f2.couleur
and ref(f1) <> ref(f2);
R3:
Résultat
Réponse:
R1
les paires de fans ayant la même couleur favorite
Résulat de R1
F1
F1
F1
F3
F2
F2
F3
F1
F3
F3
R2
idem sans les paires de fan qui ont le même nom
F1
F3
F3
F1
R3idem sans les paires contenant 2 fois le même objet
Résultat de R3:
F1
F1
F1
F3
page 5
Lettres initiales du Prénom et du Nom:
F3
page 6
F1
Exercice 2. XML et DTD
2 pts
On considère le document xml suivant :
1 <?xml version="1.0" encoding="ISO-8859-1"?>
2 <!DOCTYPE montypedoc [
3 <!ENTITY copy "right">
4 <!ELEMENT document (p*|(element,p)*)>
5 <!ELEMENT p (a|(a,b))*>
6 <!ELEMENT a (#PCDATA)>
7 <!ELEMENT b (#PCDATA)>
8 <!ELEMENT a (#PCDATA)>
9 <!ELEMENT element (#PCDATA)>
10
11 <!ATTLIST document ii ID #REQUIRED>
12 <!ATTLIST document oo ID #REQUIRED>
13
14 <!ATTLIST p att1 PCDATA #IMPLIED
15
att2 IDREFS #IMPLIED>
16 ]>
17
18 <document ii="ii" oo=aa>
19 <élément> Yo ! </élément>
20 <p att1="coucou">
21 <b>oui</b>
22 <b>non</b>
23 </p>
24
25 <p att2="ii oo">
26 <a />
27 <a><b></a>
28 </p>
29
30 %copy; moi-même & toi avec.
31 </document>
Relevez toutes les fautes de ce document, en les expliquant. Dites si ce sont des fautes de validité ou de
syntaxe xml et expliquez comment les corriger.
Lettres initiales du Prénom et du Nom:
page 7
Réponses :
Dans la DTD
Pas 2 fois la déclaration de l’élément a
Pas 2 attributs de type ID pour le même élément
Pas de type PCDATA pour un attribut
Fautes de validité :
L’élément p (ligne 20) n’est pas valide (remplacer le 1er élément b par un élément a)
La balise élément n’est aps définie (seul element, sans accent, est défini)
L’élément a ligne 27 n’est pas conforme à la DTD (pas valide)
LE document ne correspond pas au modèle (pb de validité) car il faut une séquence d’un element et d’un
p, or il y a 2 élément p. ON pourrait avoir un p tout seul, amis il aurait du être mis avant, car on a
p*|(element,p)*, mais il n’y a pas d’* sur l’ensemble.
Fautes de syntaxe :
Manque les « à la valeur de l’attribut oo ligne 18
L’entité copy ne s’appelle aps avec %, mais avec & (entité interne).
Le & est compris comme un appel d’entité (mais n’est pas suivi par un nom d’entité.) Il faut le remplacer
par &amp ;
L’élément b ligne 27 n’est pas fermé.
Exercice 3. DTD
5 pts
On souhaite écrire une DTD représentant le schéma des équipes, des joueurs et des fans, décrit ci-dessous
en SQL3 :
create type Joueur as object (
nom varchar2(30),
age number(2)
);
/
create type Ens_Joueurs as table of ref Joueur;
/
create type Ens_Couleurs as table of varchar2(30);
/
create type Equipe as object (
nom varchar2(30),
joueurs Ens_Joueurs,
capitaine ref Joueur,
couleurs Ens_Couleurs);
/
create type Ens_Equipes as table of ref Equipe;
/
Lettres initiales du Prénom et du Nom:
page 8
create type Fan as object (
nom varchar2(30),
joueurs_favoris Ens_Joueurs,
equipes_favorites Ens_Equipes,
couleur varchar2(30));
Question1. Représentez ce schéma dans le modèle Entité-Association.
Joueur
Est-composée de
Nom
age
Joueurs-favoris
capitaine
Nom
couleur
Equipe
Nom
couleurs
Fan
Equipes-favorites
Question2. Ecrire une DTD pour ce schéma, en représentant les attributs et les associations du schéma
E/A par des attributs.
Lettres initiales du Prénom et du Nom:
page 9
< !ELEMENT basejoueurs(equipe*,joueur*,fan*)>
< !ELEMENT equipe EMPTY>
< !ELEMENT joueur EMPTY>
< !ELEMENT fan EMPTY>
<!ATTLIST equipe
Nom CDATA #REQUIRED
Couleurs CDATA #IMPLIED
Capitaine IDREF #IMPLIED
Est-compose-de IDREFS #REQUIRED>
<!ATTLIST joueur
Nom ID #REQUIRED
Age CDATA #REQUIRED
>
<!ATTLIST fan
Nom CDATA #REQUIRED
Couleur CDATA #REQUIRED
Joueurs-favoris IDREFS #IMPLIED
Equipes-favorites IDREFS #IMPLIED>
Question 3. Exprimez, lorsque c’est possible, les contraintes suivantes (ou montrer que c’est déjà fait) :
Lettres initiales du Prénom et du Nom:
page 10
a) Une équipe a 11 joueurs
Impossible ou mettre 11 attributs IDREF
a) Un et un seul capitaine par équipe
Capitaine IDREF #REQUIRED
b) Les couleurs autorisées sont jaune, bleu, rouge, vert
< !ATTLIST equipe Couleurs (‘jaune’|’bleu’|’rouge’|’vert’) ’jaune’>
c) Un joueur appartient à une équipe seulement
< !ATTLIST equipe Nom ID #REQUIRED>
<!ATTLIST joueur appartient IDREF #REQUIRED>
Exercice 4 : XPath et XQuery
7 pts
/users/Enseignants/gancarsk/xquery
Soit le fichier XML family.xml suivant :
<?xml version="1.0" encoding="UTF-8"?>
<base>
<personne id = "p1" genre = "m">
<prenom>Pierre</prenom>
<nom>Rao</nom>
<age>58</age>
<conjoint idref = "p2"/>
</personne>
<personne id = "p2" genre = "f">
<prenom>Isabelle</prenom>
<nom>Rao</nom>
<age>61</age>
<conjoint idref = "p1"/>
</personne>
<personne id = "p3" genre = "m">
<prenom>Fernand</prenom>
<nom>Daile</nom>
<age>32</age>
<conjoint idref = "p4"/>
</personne>
<personne id = "p4" genre = "f">
<personne id = "p8" genre = "m">
<prenom>Louis</prenom>
<nom>Daile</nom>
<age>11</age>
<pere idref = "p3"/>
<mere idref = "p4"/>
</personne>
<personne id = "p9" genre = "f">
<prenom>Marie</prenom>
<nom>Daile</nom>
<age>10</age>
<pere idref = "p3"/>
<mere idref = "p4"/>
</personne>
<famille id = "f1">
<epoux idref = "p1"/>
<epouse idref = "p2"/>
<mariage>
<lieu>Bandol</lieu>
<date>12 fevrier 1975</date>
</mariage>
</famille>
Lettres initiales du Prénom et du Nom:
<prenom>Fernande</prenom>
<nom>Ehle</nom>
<age>30</age>
<conjoint idref = "p3"/>
<pere idref = "p1"/>
<mere idref = "p2"/>
</personne>
<famille id = "f2">
<epoux idref = "p3"/>
<epouse idref = "p4"/>
<mariage>
<lieu>Lyon</lieu>
<date>12 mars 1999</date>
</mariage>
</famille>
<personne id = "p5" genre = "f">
<prenom>Elise</prenom>
<nom>Lettra</nom>
<age>27</age>
<conjoint idref = "p7"/>
<pere idref = "p1"/>
<mere idref = "p2"/>
</personne>
<personne id = "p6" genre = "f">
<prenom>Lucie</prenom>
<nom>Daile</nom>
<age>12</age>
<pere idref = "p3"/>
<mere idref = "p4"/>
</personne>
page 11
<famille id = "f3">
<epoux idref = "p7"/>
<epouse idref = "p5"/>
<mariage>
<lieu>Bandol</lieu>
<date>3 avril 2001</date>
</mariage>
</famille>
</base>
<personne id = "p7" genre = "m">
<prenom>Jean</prenom>
<nom>Lettra</nom>
<age>35</age>
<conjoint idref = "p5"/>
</personne>
Dans tout cet exercice, on suppose (pour simplifier) que deux personnes ayant un parent en commun ont
forcément les deux parents en commun.
Question 1. Exprimez en XPath les requêtes suivantes :
1. Les tantes (du côté maternel) de Louis Daile. Résultat : la personne d’id p5
//personne[@genre='f'][mere/@idref=//personne[@id=//personne[nom='Daile'
prenom='Louis']/mere/@idref]/mere/@idref][not(@id=//personne[nom='Daile'
prenom='Louis']/mere/@idref)]
2. Prénom des mères dont au moins une fille s’est mariée à Bandol. Résultat : Isabelle
and
and
Lettres initiales du Prénom et du Nom:
page 12
//personne[@id=//personne[@id=//mariage[lieu='Bandol']/../epouse/@idref]/mere/@idref]/prenom/text()
3. Prénom des personnes n’ayant pas d’enfant. Réponse : Elise, Lucie, Jean, Louis, Marie.
//personne[not(@id=(//personne/pere/@idref|//personne/mere/@idref)]
4. Prénom des personnes dont l’âge est supérieur à la somme des âges de Lucie Daile et de ses frères et
sœurs. Résultat : Pierre, Isabelle, Jean
//personne[age
>
sum(//personne[pere/@idref=//personne[nom='Daile'
prenom='Lucie']/pere/@idref]/age)]/prenom/text()
and
Question 2. Ecrire en XQuery les requêtes suivantes :
1. Donner la liste des femmes (nom, prenom, age) ayant leurs parents dans la base, avec la moyenne
d’âge de leurs parent (map) et celle de leurs frères et sœurs (maf), le tout sous forme d’attributs Le
résultat doit être ordonné, de la plus grande maf à la plus petite :
<liste_femmes>
<Madame nom="Lettra" prenom="Elise" age="27" map="59.5" maf="30"/>
<Madame nom="Ehle" prenom="Fernande" age="30" map="59.5" maf="27"/>
<Madame nom="Daile" prenom="Marie" age="10" map="31" maf="11.5"/>
<Madame nom="Daile" prenom="Lucie" age="12" map="31" maf="10.5"/>
Lettres initiales du Prénom et du Nom:
page 13
</liste_femmes>
<liste_femmes>
{ for $p in document("family.xml")//personne[@genre='f']
let $nomp:=$p/nom
let $prenomp:=$p/prenom
let $agep:= $p/age
let $pere:=document("family.xml")//personne[@id=$p/pere/@idref]
let $mere:=document("family.xml")//personne[@id=$p/mere/@idref]
let $fratrie := document("family.xml")//personne[pere/@idref=$pere/@id and @id !=
$p/@id]
where exists($pere)and exists($mere)
order by avg($fratrie/age) descending
return
<Madame nom="{$nomp}" prenom="{$prenomp}" age="{$agep}" map="{($pere/age +
$mere/age) div 2}" maf="{avg($fratrie/age)}"/>
}
Lettres initiales du Prénom et du Nom:
page 14
</liste_femmes>
2 .Donner la liste des hommes avec pour chacun, sous forme d’attribut, le nom et le prénom et s’il y en a,
le nombre de ses enfants suivi de ' : ' et de leurs prénoms, ou sinon "aucun". Lorsque certains enfants sont
marié, on indique,par des sous-éléments, le lieu de leur mariage.Le résultat doit être :
<liste_pères>
<Père nom="Rao" prenom="Pierre" enfants="2 : Fernande Elise">
<enfant_marié à="Lyon"/>
<enfant_marié à="Bandol">
</Père>
<Père nom="Daile" prenom="Fernand" enfants="3 : Lucie Louis Marie"> </Père>
<Père nom="Lettra" prenom="Jean" enfants="aucuns"></Père>
<Père nom="Daile" prenom="Louis" enfants="aucuns"></Père>
</liste_pères>
<liste_pères>
{ for $p in document("family.xml")//personne[@genre='m']
let $nomp:=$p/nom
let $prenomp:=$p/prenom
let $enfants:=document("family.xml")//personne[$p/@id=pere/@idref]
return
<Père
nom="{$p/nom}"
prenom="{$p/prenom}"
enfants="{if
($enfants)
then
(count($enfants),":", $enfants/prenom) else ("aucuns")}">
{for $enfant in $enfants,
$mariage in document("family.xml")//mariage[$enfant/@id = ../(epoux|epouse)/@idref]
Lettres initiales du Prénom et du Nom:
page 15
return
<enfant_marié à="{$mariage/lieu}"/>
}
</Père>}
</liste_pères>
3.Donner l’ensemble de la famille 'f1', génération par génération, en donnant le nom et le prénom de
chacun. Le résultat doit être :
<famille_f1>
<grandpère><prenom>Pierre</prenom><nom>Rao</nom></grandpère>
<grandmère><prenom>Isabelle</prenom><nom>Rao</nom></grandmère>
<enfants>
<enfant><prenom>Fernande</prenom><nom>Ehle</nom></enfant>
<enfant><prenom>Elise</prenom><nom>Lettra</nom></enfant>
</enfants>
<petits_enfants>
<petit_enfant><prenom>Lucie</prenom><nom>Daile</nom></petit_enfant>
<petit_enfant><prenom>Louis</prenom><nom>Daile</nom></petit_enfant>
<petit_enfant><prenom>Marie</prenom><nom>Daile</nom></petit_enfant>
</petits_enfants>
</famille_f1>
let
let
let
let
$d:=document("family.xml")
$frao:=$d//famille[@id="f1"]
$gprao:=$d//personne[@id=$frao/epoux/@idref]
$gmrao:=$d//personne[@id=$frao/epouse/@idref]
return
<famille_f1>
<grandpère> {$gprao/(prenom|nom)} </grandpère>
<grandmère> {$gmrao/(prenom|nom)} </grandmère>
<enfants>
{for $enfant in document("family.xml")//personne[pere/@idref=$gprao/@id]
return
<enfant> {$enfant/(prenom|nom)} </enfant>
}
Lettres initiales du Prénom et du Nom:
page 16
</enfants>
<petits_enfants>
{for $penfant in document("family.xml")//personne[(pere|mere)/@idref=$d//personne
[pere/@idref=$gprao/@id]/@id]
return
<petit_enfant> {$penfant/(prenom|nom)} </petit_enfant>
}
</petits_enfants>
</famille_f1>
4. Retourner la moyenne d’âge des personnes de la base, suivie des personnes (nom, prénom) plus âgées
que cette moyenne.
On obtient le résultat suivant :
<résultat>
<age_moyen>30</age_moyen>
<personne><nom>Rao</nom><prenom>Pierre</prenom><age>58</age></personne>
<personne><nom>Rao</nom><prenom>Isabelle</prenom><age>61</age></personne>
<personne><nom>Daile</nom><prenom>Fernand</prenom><age>32</age></personne>
<personne><nom>Lettra</nom><prenom>Jean</prenom><age>35</age></personne>
</résultat>
let $personnes:=document("family.xml")//personne
let $am:=avg($personnes/age)
return
<résultat>
Lettres initiales du Prénom et du Nom:
<age_moyen>
{$am}
</age_moyen>
{for $p in $personnes[age > $am]
return
<personne>
{$p/nom}
{$p/prenom}
{$p/age}
</personne>
}
</résultat>>
page 17