diff --git a/EXOS/Partiel2020.tex b/EXOS/Partiel2020.tex index e0c0dae..69b9e43 100644 --- a/EXOS/Partiel2020.tex +++ b/EXOS/Partiel2020.tex @@ -11,6 +11,13 @@ \usepackage{slashbox} %\usepackage{times} + +\usepackage{tikz,pgflibraryarrows,pgffor,pgflibrarysnakes} +\usetikzlibrary{decorations.pathreplacing} + +\usepackage{color, colortbl} +\definecolor{Gray}{gray}{0.9} + \usepackage{fancyvrb} \fancypagestyle{monstyle}{ @@ -27,7 +34,7 @@ %\fancyhead[CE]{\slshape CE} %\fancyhead[RE]{\slshape RE} -\fancyhead[LO]{\bfseries 2018-2019 BD PLS/SQL\rightmark} +\fancyhead[LO]{\bfseries 2019-2020 BD PLS/SQL\rightmark} %\fancyhead[CO]{\slshape APF} \fancyhead[RO]{\bfseries ~\leftmark } @@ -188,138 +195,373 @@ End; \newpage -\begin{exercice}[Soldes] (20 points) -Afin de préparer les soldes d’hiver, écrivez un fichier de commandes -SQL qui, pour un produit saisi par l’utilisateur, si le stock est plus -grand que 100 alors le prix est diminué de 10\% et si le stock plus -grand que 200 alors le prix est diminué de 20\%. Enfin si le stock est -vide alors ajouter dans la table \code{Tligne} une phrase pour -indiquer qu’il faut recommander ce produit en donnant son numéro de -produit. -\end{exercice} +\section*{PL/SQL : NBA Statistiques} +Ci-dessous un mod\`ele de la base de donn\'ees de statistiques de la +NBA (National Basketball Association), o\`u PG, SG, SF, PF et C sont +les diff\'erents postes occup\'es par les joueurs sur le terrain. Un +joueur ne peut pas \^etre en activit\'e dans deux \'equipes en m\^eme temps. + +\begin{center} + \begin{tikzpicture}[every node/.style={inner sep=0,outer sep=0}] + +\node (i) at (6,0) {\begin{varwidth}{1.5in} +\begin{tabular}{|l|} +\hline +\rowcolor{Gray}CONTRAT\\ +\hline +\underline{id\_contrat}\\ +\#id\_joueur\\ +\#id\_equipe\\ +Date\_debut\\ +Date\_fin\\ +Salaire\_jour\\ \hline +\end{tabular} +\end{varwidth} +}; + + +\node (a) at (0,0) {\begin{varwidth}{2.5in} +\begin{tabular}{|l|} +\hline +\rowcolor{Gray}JOUEUR\\ +\hline +\underline{id\_joueur}\\ +Nom\\ +Pénom\\ +Date\_de\_naissance\\ +Taille\\ +Poste('PG','SG','SF','PF','C')\\ +\hline +\end{tabular} +\end{varwidth} +}; + + +\node (f) at (8,-5) {\begin{varwidth}{2.5in} +\begin{tabular}{|l|} +\hline +\rowcolor{Gray}Match\\ +\hline +\underline{id\_match}\\ +Date\_match\\ +\#id\_equipe\_domicile\\ +\#id\_equipe\_exterieur\\ +Ville\\ +Categorie(Amical,Saison,Playoff,Allstar)\\ +Score\_domicile\\ +Score\_exterieur\\ +Prolongation\\ +\hline +\end{tabular} +\end{varwidth} +}; + +\node[draw,rectangle] (g) at (0,-5) {\begin{varwidth}{2in} +\begin{tabular}{l} + \rowcolor{Gray}JOUE\\ + \hline + \underline{\#id\_joueur}\\ + \underline{\#id\_match}\\ + Points\\ + Rebonds\\ + Interceptions\\ + Contres\\ + Passes\\ + Balles\_perdues\\ + Fautes\\ +\end{tabular} +\end{varwidth}}; + + + +\node[draw,rectangle] (c) at (11,0) { +\begin{tabular}{|l|} +\hline +\rowcolor{Gray}EQUIPE\\ +\hline +\underline{id\_equipe}\\ +Nom\\ +Ville\\ +Conference('Est','Ouest')\\ +Date\_creation\\ +\hline +\end{tabular} +}; + +\draw[-latex] (i) -- (a); +\draw[-latex] (i) -- (c); +\draw[-latex] (10,-2.6) -- (10.65,-1.5); +\draw[latex-] (c) -- (f); +\draw[latex-] (f) -- (g); +\draw[latex-] (a) -- (g); + + \end{tikzpicture} +\end{center} + + \newpage + +\begin{exercice}[NBA, PLSQL] (45 points) +Le MLD ci-dessus stocke les donn\'ees des matchs NBA. + +\begin{enumerate} + +\item (15 points) \'Ecrire un code PL/SQL qui permet de saisir un + nouveau joueur en entrant les six champs n\'ecessaires. Lever une + exception la clef primaire saisie n'est pas valide. + -\begin{SaveVerbatim}{VerbSolde} +\begin{SaveVerbatim}{saisie} DROP TABLE tligne ; CREATE TABLE tligne (ligne varchar2(100)) ; -set echo off ; set verify off ; set feed off; -variable vnoproduit char(4) -prompt Entrer la reference du fournisseur : -accept vnoproduit +set echo off; set verify off; set feedback off; + +variable vidjoueur char(4) +prompt Entrer l idjoueur +accept vidjoueur + +variable vnom varchar2(200) +prompt Entrer le nom du joueur +accept vnom + +variable vprenom varchar2(200) +prompt Entrer le prenom du joueur +accept vprenom + +variable vdate date +prompt Entrer sa date de naissance +accept vdate + +variable vtaille NUMBER +prompt Entrer sa taille +accept vtaille + +variable vposte char(2) +prompt Entrer l'idjoueur +accept vposte DECLARE -dstock number; +dnbid; +EXISTEDEJAJ EXCEPTION; +didjoueur char(4); BEGIN -SELECT count(stock) INTO dstock -FROM Tproduit -Where noproduit=’&vnoproduit’; - -If dstock = 0 then - INSERT INTO tligne VLAUES (‘Stock Null pour ce produit - ’||’&vnoporduit’||’Recommander ’) ; - End if; -If dstock >200 then - UPDATE Tproduit SET prixv=dprix*1.2 WHERE noproduit=’&vnoproduit’; - Else If dstock > 100 then - UPDATE Tproduit SET prixv=dprix*1.1 WHERE noproduit=’&vnoproduit’; -End if; -End; -. -/ -SELECT * FROM tligne ; -set verify on ; set feed on ; set echo on ; +SELECT count(*) INTO dnBid FROM JOUEUR WHERE id_joueur ='&vidjoueur'; +IF dnbid > 0 THEN RAISE EXCEPTION +END IF; + +INSERT INTO tligne VALUES ('&vidjoueur','&vnom','&prenom',to_date('&vdate',DD/MM/YYYY),'&vtaille','&vposte'); + +EXCEPTION +WHEN EXISTEDEJA THEN +NSERT INTO tligne VALUES ('ID joueur existe'); +END; +./ +set echo on; set verify on; set feedback on; \end{SaveVerbatim} -\cache{%\begin{small} - \BUseVerbatim{VerbSolde} -% \end{small} + + +\cache{\begin{small} + \BUseVerbatim{saisie} + \end{small} } -\newpage -\begin{exercice}[Fournisseur] (20 points) -Ecrire un fichier de commandes SQL qui demande un numéro de produit et -qui retourne le message ‘le produit n’a pas de fournisseur’ ou ‘le -produit a plusieurs fournisseurs’, ou le 'Nom' du fournisseur s’il -n’en a qu’un. Le résultat sera placé dans une table \code{Tligne - (LIGNE varchar2(200))} et contiendra le message et le code d’erreur -produit par Oracle. -\end{exercice} -\begin{SaveVerbatim}{Verbfour} + \newpage + +\item (15 points) \'Ecrire un code PL/SQL qui, pour un + \code{id\_joueur} saisi par l'utilisateur, liste dans une table + \code{TLIGNES} son maximum de points inscript lors d'un match. La + solution propos\'ee doit mettre en place {\bf deux} m\'ecanismes un + {\bf avec} et un {\bf sans} \code{EXCEPTION} pour traiter les cas + d'erreurs suivants : + \begin{itemize} + \item \code{'joueur inconnu'}, il n'y a pas le joueur dans la table \code{JOUEUR}, + \item \code{'joueur n a pas fait de match'}, il n'apparait pas + dans la table \code{JOUE}. + \end{itemize} + +\begin{SaveVerbatim}{Maxpoints} DROP TABLE tligne ; CREATE TABLE tligne (ligne varchar2(100)) ; -set echo off ; set verify off ; set feed off ; +set echo off; set verify off; set feedback off; -variable vreffourn char(4) -prompt Entrer la reference du produit : -accept vnoproduit +variable vidjoueur char(4) +prompt Entrer la reference du joueur : +accept vidjoueur DECLARE -dnomfour char(20) ; -dreffour char(4) +dmaxpoint number; +dnbjoueur number; +didjoueur char(4); BEGIN -SELECT refourn INTO dreffour FROM Tproduitfourn -WHERE nopoduit ='&vnoproduit' ; +SELECT count(Nom) INTO dnbjoueur FROM JOUEUR WHERE id_joueur ='&vidjoueur'; -SELECT Nom INTO dnomfour FROM TFounisseur -Where ref-fourn='dreffour; +if dnbjoueur != 0 then -INSERT INTO tligne VALUES (dnomfour) ; +SELECT max(points) INTO dmaxpoint FROM JOUE +WHERE id_joueur ='&vidjoueur'; + +INSERT INTO tligne VALUES ('Max points de'||'&vidjoueur'||' : '||to_char(dmaxpoint)); +ELSE +INSERT INTO tligne VALUES('count detecte numero du joueur pas bon'); + +SELECT id_joueur INTO didjoueur FROM JOUEUR +WHERE id_joueur ='&vidjoueur'; +end if; EXCEPTION when no_data_found then -INSERT INTO tligne VALUES(TO_CHAR(SQLCODE)||' '||SQLERRM||' Le produit -n''a pas de fournisseur' ) ; -when too_many_rows then -INSERT INTO tligne VALUES(O_CHAR(SQLCODE)||' '||SQLERRM||' Le produit a -plusieurs fournieeurs) ; -End ; +INSERT INTO tligne VALUES('exception numero du joueur pas bon'); +end ; . / + SELECT * FROM tligne ; -set verify on ; set feed on ; set echo on ; +set verify on; set feedback on; set echo on; \end{SaveVerbatim} -\cache{%\begin{small} - \BUseVerbatim{Verbfour} -% \end{small} +\cache{\begin{small} + \BUseVerbatim{Maxpoints} + \end{small} } \newpage -\begin{exercice}[Curseur] (20 points) -Ecrivez un fichier de commandes SQL qui diminue de 10\% les prix des -produits qui ont un stock de plus de 500. -\end{exercice} -\begin{SaveVerbatim}{Verbcinq} -set echo off ; set verify off ; set feed off ; + +\item (15 points) \'Ecrire un code PL/SQL qui liste dans une table + \code{TLIGNES} les joueurs en activit\'e (ayant une date de fin de + contrat non nulle) du plus vieux au plus jeune. + +\begin{center} +\begin{verbatim} + Nom Prenom Date de naissance Nom Equipe Actuelle + XXXXXX XXXXXXX XX/XX/XXXX XXXXXXXX + XXXXXX XXXXXXX XX/XX/XXXX XXXXXXXX + XXXXXX XXXXXXX XX/XX/XXXX XXXXXXXX + ... +\end{verbatim} +\end{center} + +\begin{SaveVerbatim}{Joueur} +DROP TABLE tligne ; +CREATE TABLE tligne (ligne varchar2(100)) ; -Declare -dprix Tproduit.prix%TYPE ; +set echo off; +set verify off; +set feedback off; -CURSOR r IS SELECT prixv FROM Tproduit WHERE Tproduit.stock >500 -FOR UPDATE ; +DECLARE +dnom varchar2(20); +dprenom varchar2(20); +ddate date; +dnomequipe varchar2(20); + +CURSOR c IS SELECT j.Nom, j.Prenom, j.Date_de_naissance, e.Nom FROM JOUEUR j, APPARTIENT a, EQUIPE e +WHERE a.id_joueur = j.id_joueur and e.id_equipe = a.id_equipe and a.Date_fin is NULL +Order by Date_de_naissance; BEGIN -OPEN r ; -FETCH r INTO dprix ; -WHILE r%FOUND -LOOP -UPDATE Tproduit SET prixv=dprix*1.1 WHERE CURRENT of r ; - FETCH r INTO dprix ; -END LOOP ; -COMMIT ; -CLOSE R ; -END ; +OPEN c; + +INSERT INTO tligne VALUES ('Nom Prenom Date de naissance Nom Equipe Actuelle'); +FETCH c INTO dnom, dprenom, ddate, dnomequipe; + +WHILE c%found +LOOP + INSERT INTO tligne VALUES (dnom||' '||dprenom||' '||to_char(ddate)||' '||dnomequipe); + FETCH c INTO dnom, dprenom, ddate, dnomequipe; +END LOOP; + +CLOSE C; +END; . / -set verify on ; set feed on ; set echo on ; + +SELECT * FROM tligne ; +set verify on; +set feedback on; +set echo on; \end{SaveVerbatim} -\cache{%\begin{small} - \BUseVerbatim{Verbcinq} -% \end{small} -} + + \cache{%\begin{small} + \BUseVerbatim{Joueur} + %\end{small} + } + +%% \item (20 points) Lister dans une table \code{TLIGNES} tous les +%% joueurs ayant particip\'e \`a un ALLSTAR de la conf\'erence Est et +%% ceux de la conf\'erence Ouest avec les informations suivantes : +%% \begin{center} +%% \begin{small} +%% \begin{verbatim} +%% ALLSTAR MATCH +%% EQUIPE de l'EST +%% Nom Prenom Poste Equipe Actuelle +%% XXXXXX XXXXXXX XXXXXX XXXXXXXX +%% XXXXXX XXXXXXX XXXXXX XXXXXXXX +%% EQUIPE de l'EST +%% Nom Prenom Poste Equipe Actuelle +%% XXXXXX XXXXXXX XXXXXX XXXXXXXX +%% XXXXXX XXXXXXX XXXXXX XXXXXXXX +%% \end{verbatim} +%% \end{small} +%% \end{center} + + +%% \begin{SaveVerbatim}{Allstar} +%% DECLARE +%% dnom varchar2(20); dprenom varchar2(20); +%% dposte char(2); dnomequipe varchar2(20); + +%% CURSOR Cest IS SELECT j.Nom, j.Prenom, j.Poste, e.Nom FROM JOUEUR j, +%% APPARTIENT a, EQUIPE e WHERE a.id_joueur = j.id_joueur and e.id_equipe +%% = a.id_equipe and e.conference='Est' and j.id_joueur in (SELECT +%% id_joueur FROM JOUE je, GAME g where g.Categorie='Allstar' and +%% g.id_game=je.id_game); + +%% CURSOR Couest IS SELECT j.Nom, j.Prenom, j.Poste, e.Nom FROM JOUEUR j, +%% APPARTIENT a, EQUIPE e WHERE a.id_joueur = j.id_joueur and e.id_equipe +%% = a.id_equipe and e.conference='Ouest' and j.id_joueur in (SELECT +%% id_joueur FROM JOUE je, GAME g where g.Categorie='Allstar' and +%% g.id_game=je.id_game); + +%% BEGIN +%% INSERT INTO tligne VALUES ('ALLSTAR GAME); +%% INSERT INTO tligne VALUES ('Conference Est'); +%% INSERT INTO tligne VALUES ('Nom Prenom Poste Nom Equipe Actuelle'); +%% OPEN Cest; +%% FETCH Cest INTO dnom, dprenom, dposte, dnomequipe; +%% WHILE Cest%found LOOP +%% INSERT INTO tligne VALUES (dnom||' '||dprenom||' '||dposte||' '||dnomequipe); +%% FETCH Cest INTO dnom, dprenom, dposte, dnomequipe; +%% END LOOP; +%% CLOSE Cest; +%% INSERT INTO tligne VALUES ('Conference Ouest'); +%% OPEN Couest; +%% INSERT INTO tligne VALUES ('Nom Prenom Poste Nom Equipe Actuelle'); +%% FETCH Couest INTO dnom, dprenom, dposte, dnomequipe; +%% WHILE Couest%found LOOP +%% INSERT INTO tligne VALUES (dnom||' '||dprenom||' '||dposte||' '||dnomequipe); +%% FETCH Couest INTO dnom, dprenom, dposte, dnomequipe; +%% END LOOP; +%% CLOSE Couest; +%% END; +%% . +%% / +%% SELECT * FROM tligne ; +%% \end{SaveVerbatim} + +%% \cache{\begin{footnotesize} +%% \BUseVerbatim{Allstar} +%% \end{footnotesize} +%% } +\end{enumerate} + +\end{exercice} + +