You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

752 lines
18 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

\documentclass[a4paper,11pt]{article}
\usepackage[utf8x]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[french]{babel}
\usepackage[a4paper,hmargin=20mm,vmargin=30mm]{geometry}%\usepackage{fullpage}
\usepackage{url}
\usepackage{comment}
\usepackage{fancyhdr}% fancy header
\usepackage{multirow}
\usepackage{slashbox}
\usepackage{color, colortbl}
\definecolor{Gray}{gray}{0.9}
\usepackage{adjustbox}
\usepackage{slashbox}
%\usepackage{times}
\usepackage{tikz,pgflibraryarrows,pgffor,pgflibrarysnakes}
\usetikzlibrary{decorations.pathreplacing}
\usepackage{pdfpages}
\usepackage{fancyvrb}
\fancypagestyle{monstyle}{
%\fancyhead{}
\renewcommand{\headrulewidth}{1pt}
%% %\renewcommand{\footrulewidth}{0.4pt}
% \fancyhead[LE]{\slshape \thepage/ \pageref{LastPage}}
%% \fancyhead[RO]{\slshape \thepage/ \pageref{LastPage}}
%\fancyhf{}
%\fancyhead[LE]{\slshape LE}
%\fancyhead[CE]{\slshape CE}
%\fancyhead[RE]{\slshape RE}
\fancyhead[LO]{\bfseries 2020-2021 BD PLS/SQL\rightmark}
%\fancyhead[CO]{\slshape APF}
\fancyhead[RO]{\bfseries ~\leftmark }
%% %\fancyfoot{}
% \fancyfoot[LE,RO]{}
\fancyfoot[CO,CE]{}%\slshape\thepage/\pageref{LastPage}}
%% %\fancyfoot[LO,RE]{\small\slshape \ddmmyyyydate version du \today}
}
% \pagestyle{fancy}
\usepackage{amsmath}
\usepackage{amsthm}
\theoremstyle{definition}
\newtheorem{exercice}{Exercice}
\pagestyle{monstyle}
\usepackage{amsmath}
\usepackage{amsthm}
\newcommand{\code}[1]{\texttt{#1}}
\usepackage{boxedminipage}
\usepackage{setspace}
\newsavebox\svbx
\newif\ifcache
\long\def\cache#1{\ \newline
\setbox\svbx=\vbox{\leavevmode \newline \begin{spacing}{1}#1\end{spacing}}
\smallskip\par\noindent
\begin{boxedminipage}{\linewidth}
\ifcache
\leavevmode\hrule height 0pt\vskip \ht\svbx\hrule height 0pt
\else \unvbox\svbx
\fi
\end{boxedminipage}
\par\smallskip}
\cachefalse % version prof
%\cachetrue % version etudiant
\begin{document}
\begin{center}
NOM : \hfill Examen \hfill~\\
PRENOM : \hfill 90 minutes%% , 75 points
\hfill ~\\
GROUPE : \hfill \hfill~\\
\end{center}
\section*{PL/SQL : R\'eservation d'un terrain de sport}
Une entreprise de location de terrain de badminton/padel souhaite
informatiser la gestion de ses locaux. Chaque terrain possède un
numéro : il y a 10 terrains de badminton numérotés de 1 à 10, et 2 de
padels de 1 à 2. Il est possible qu'il y ait entre 2 et 4 joueurs pour
le badminton, mais exactement 4 joueurs pour le padel. Les tarifs
horaires pour la location du terrain ne sont pas les mêmes pour le
badminton et le padel. Ils varient également en fonction de
l'horaire. La réservation se fait pour un créneau dont lheure de
début est connue (9h , 10h, ... , 17h) et la durée spécifique au sport
pratiqué (1h ou 2h). Une fois sur place, il est également possible de
louer des équipements (raquettes et chaussures) pour un supplément :
\begin{center}
\begin{tabular}{|l|c|c|}
\hline
Prix à lunité & BADMINTON & PADEL \\ \hline
Raquette & 1€ & 2€ \\ \hline
Paire de chaussures& 2€ & 3€ \\ \hline
\end{tabular}
\end{center}
Lors d'une réservation, il faut connaître au moins les coordonnées
d'un des joueurs pour savoir qui a fait la réservation. Lors d'une
réservation en ligne, il est possible d'inscrire le nom et le numéro
de téléphone des joueurs, afin qu'un rappel leur soit envoyé le jour
de leur réservation. Il faut pouvoir sortir une facture avec le
montant total de la réservation ; c'est à dire le tarif de la location
en fonction du sport et du créneau horaire, ainsi que des équipements
loués.
MCD de lapplication :
\newpage
\begin{center}
\includegraphics{MCD.png}
\end{center}
\begin{center}
\begin{tikzpicture}[every node/.style={inner sep=0,outer sep=0}]
\node (i) at (5,3) {\begin{varwidth}{1.5in}
\begin{tabular}{|l|}
\hline
\rowcolor{Gray}EQUIPEMENT\\
\hline
\underline{idEquipement}\\
Libell\'e\\
Tarif\\ \hline
\end{tabular}
\end{varwidth}
};
\node (w) at (5,-1) {\begin{varwidth}{1.5in}
\begin{tabular}{|l|}
\hline
\rowcolor{Gray}RESERVATION\\
\hline
\underline{idReservation}\\
dateReserv\\
nbJoueurs\\ \hline
\end{tabular}
\end{varwidth}
};
\node (a) at (0,0) {\begin{varwidth}{2.5in}
\begin{tabular}{|l|}
\hline
\rowcolor{Gray}TERRAIN\\
\hline
\underline{idTerrain}\\
numTerrain\\
\hline
\end{tabular}
\end{varwidth}
};
\node (f) at (8,-5) {\begin{varwidth}{2.5in}
\begin{tabular}{|l|}
\hline
\rowcolor{Gray}CRENEAU\\
\hline
\underline{numCreneau}\\
heureD\'ebut\\
\hline
\end{tabular}
\end{varwidth}
};
\node[draw,rectangle] (g) at (0,-5) {\begin{varwidth}{2in}
\begin{tabular}{l}
\rowcolor{Gray}SPORT\\
\hline
\underline{nomSport}\\
nbMinJoueurs\\
nbMaxJoueurs\\
dur\'ee\\
\end{tabular}
\end{varwidth}};
\node[draw,rectangle] (c) at (11,0) {
\begin{tabular}{|l|}
\hline
\rowcolor{Gray}JOUEUR\\
\hline
\underline{idjoueur}\\
Nom\\
Pénom\\
num\'ero\\
\hline
\end{tabular}
};
\draw[-latex] (i) -- (a);
\draw[-latex] (i) -- (c);
\draw[latex-] (c) -- (f);
\draw[latex-] (f) -- (g);
\draw[latex-] (a) -- (g);
\end{tikzpicture}
\end{center}
\newpage
Modèle relationnel :
EQUIPEMENT(\underline{idEquipement}, libell\'e, tarif)
CONTENIR(\underline{idReservation}, \underline{idEquipement}, nombre)
TERRAIN(\underline{idTerrain}, numTerrain, nomSport)
RESERVATION(\underline{idReservation}, dateReserv, nbJoueurs, idTerrain, numCreneau)
FAIRE(\underline{idReservation}, \underline{idJoueur})
JOUEUR(\underline{idJoueur}, nom, pr\'enom, num\'ero)
SPORT(\underline{nomSport}, nbMinJoueurs, nbMaxJoueurs, dur\'ee)
FACTURER(\underline{nomSport}, \underline{numCreneau}, tarifHoraire)
CRENEAU(\underline{numCreneau}, heureD\'ebut)
Ordres de création des tables :
\begin{verbatim}
create table EQUIPEMENT (
idEquipement char(3) primary key,
libelle varchar2(20),
tarif number(5,2));
create table JOUEUR (
idJoueur char(2) primary key,
nom varchar2(20),
pnom varchar2(20),
numero number);
create table CRENEAU (
numCreneau char(2) primary key,
heureDebut number(2));
create table TERRAIN (
idTerrain char(3) primary key,
numTerrain number,
nomSport varchar2(10) );
create table SPORT (
nomSport varchar2(10),
nbMinJoueurs number,
nbMaxJoueurs number,
duree number);
create table RESERVATION (
idReserv char(3) primary key,
dateReserv date,
nbJoueurs number,
idTerrain char(5) references TERRAIN,
numCreneau char(2) references CRENEAU );
create table faire (
idReserv char(3) references RESERVATION,
idJoueur char(2) references JOUEUR,
primary key(idReserv, idJoueur));
create table contenir (
idReserv char(3) primary key,
idEquipement char(3),
nombre number);
\end{verbatim}
Consignes :
\begin{itemize}
\item Les résultats seront affichés avec une table Tresultat (ligne varchar2 (200))
\item La partie SQL+ nest pas demandée pour les exercices 2 et 3
\end{itemize}
\begin{exercice}[PLSQL] (30 points)
Donner le programme (partie SQL + et PL/SQL) permettant denregistrer un sport.
Messages à prévoir :
\begin{itemize}
\item Le nom du sport est déjà attribué
\item Le nombre maximum de joueurs ne peut être inférieur au nombre minimum
\item La durée est de 1h ou 2h
\item Le sport a été enregistré : nom du sport
\end{itemize}
\begin{SaveVerbatim}{Maxpoints}
DROP TABLE tligne ;
CREATE TABLE tligne (ligne varchar2(100)) ;
set echo off; set verify off; set feedback off;
variable vidjoueur char(4)
prompt Entrer la reference du joueur :
accept vidjoueur
DECLARE
dmaxpoint number;
dnbjoueur number;
didjoueur char(4);
BEGIN
SELECT count(Nom) INTO dnbjoueur FROM JOUEUR WHERE id_joueur ='&vidjoueur';
if dnbjoueur != 0 then
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('exception numero du joueur pas bon');
end ;
.
/
SELECT * FROM tligne ;
set verify on; set feedback on; set echo on;
\end{SaveVerbatim}
%% \cache{%\begin{small}
%% \BUseVerbatim{Maxpoints}
%% % \end{small}
%}
%% \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)) ;
set echo off;
set verify off;
set feedback off;
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 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;
.
/
SELECT * FROM tligne ;
set verify on;
set feedback on;
set echo on;
\end{SaveVerbatim}
%% \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{exercice}
%% \begin{center}
%% \begin{tikzpicture}[every node/.style={inner sep=0,outer sep=0}]
%% \node (a) at (5,-4) {\begin{varwidth}{1.5in}
%% \begin{tabular}{|l|}
%% \hline
%% \rowcolor{Gray}AFFECTATION\\
%% \hline
%% \underline{id\_contrat}\\
%% \#id\_personnel\\
%% \#id\_patient\\
%% Date\_debut\\
%% Date\_fin\\ \hline
%% \end{tabular}
%% \end{varwidth}
%% };
%% \node (f) at (0,0) {\begin{varwidth}{2.5in}
%% \begin{tabular}{|l|}
%% \hline
%% \rowcolor{Gray}FONCTION\\
%% \hline
%% \underline{id\_fonction}\\
%% Designation\\
%% Salaire\\
%% \hline
%% \end{tabular}
%% \end{varwidth}
%% };
%% \node (p) at (5,0) {\begin{varwidth}{2.5in}
%% \begin{tabular}{|l|}
%% \hline
%% \rowcolor{Gray}PERSONNEL\\
%% \hline
%% \underline{id\_personnel}\\
%% \#id\_fonction\\
%% \#id\_hopital\\
%% Nom\\
%% Prenom\\
%% \hline
%% \end{tabular}
%% \end{varwidth}
%% };
%% \node[draw,rectangle] (pa) at (0,-4) {\begin{varwidth}{2in}
%% \begin{tabular}{l}
%% \rowcolor{Gray}PATIENT\\
%% \hline
%% \underline{id\_patient}\\
%% Nom\\
%% Prenom\\
%% Date\_naissance\\
%% \end{tabular}
%% \end{varwidth}};
%% \node[draw,rectangle] (h) at (9,0) {
%% \begin{tabular}{|l|}
%% \hline
%% \rowcolor{Gray}HOPITAL\\
%% \hline
%% \underline{id\_hopital}\\
%% Nom\\
%% Ville\\
%% Date\_creation\\
%% \hline
%% \end{tabular}
%% };
%% \draw[-latex] (p) -- (f);
%% \draw[-latex] (p) -- (h);
%% \draw[latex-] (p) -- (a);
%% \draw[latex-] (pa) -- (a);
%% \end{tikzpicture}
%% \end{center}
\begin{exercice}[PLSQL] (45 points)
Donner le programme permettant la suppression dun joueur à condition
quil nait pas fait de réservations pour aujourdhui ou dans le
futur. Lidentifiant du joueur aura été précédemment lu dans la
variable \code{vidJoueur}. Messages à prévoir, utilisation dau moins
une exception utilisateur:
\begin{itemize}
\item Joueur inconnu
\item Impossible, il existe des réservations faites par ce joueur pour aujourdhui ou dans le futur
\item Nb actions de réservations faites dans le passé par ce joueur ont été supprimées
\item Joueur supprimé
\end{itemize}
\end{exercice}
\begin{exercice}[PLSQL] (45 points)
Donner le programme permettant dafficher les réservations actuelles
ou futures par créneau horaire pour un sport donné. On utilisera le
nom du sport contenu dans la variable \code{vnomSport}. On affichera les
résultats dans lordre croissant de lheure de début, puis de la
date de réservation.
\begin{SaveVerbatim}{Affichage}
Heure de début : XX
Id réservation date : XX/XX/XX
Id réservation date : XX/XX/XX
Id réservation date : XX/XX/XX
...
Heure de début : XX
Id réservation date : XX/XX/XX
Id réservation date : XX/XX/XX
...
Nombre de réservations total pour ce sport : nb
\end{SaveVerbatim}
% \cache{%\begin{small}
\BUseVerbatim{Affichage}
%\end{small}
% }
\begin{SaveVerbatim}{Insertion}
TODO
\end{SaveVerbatim}
%% \cache{%\begin{small}
%% \BUseVerbatim{Insertion}
%% % \end{small}
%% }
\end{exercice}
\section*{Rappels}
Les fonctions \code{connexion}, \code{deconnexion} et \code{sql\_error}
sont rappell\'ees ci-dessous. Elles ne sont pas \`a r\'e\'ecrire sur
vos copies, mais \`a utiliser dans les exercices si besoin.
\begin{verbatim}
void connexion()
{ VARCHAR uid[50];
char login[20];
char passwd[20];
printf("Donner votre login : ");
scanf("%s",login);
printf("\nDonnez votre mot de passe Oracle : ");
scanf("%s",passwd);
printf("\n");
strcpy(uid.arr,login);
strcat(uid.arr,"/");
strcat(uid.arr,passwd);
strcat(uid.arr,"@kirov");
uid.len=strlen(uid.arr);
EXEC SQL CONNECT :uid;
if (sqlca.sqlcode==0)
printf(" Connexion réussie avec succès.\n\n");
else
{
printf ("Problème à la connexion.\n\n");
exit(1);
}}
\end{verbatim}
\begin{verbatim}
void deconnexion(int validation)
{
if (validation == 1)
{ EXEC SQL COMMIT WORK RELEASE;
} else
{ EXEC SQL ROLLBACK WORK RELEASE;}
printf("Déconnexion sans problème.\n");
}
\end{verbatim}
\begin{verbatim}
void sql_error(char *msg)
{ char err_msg[128];
long buf_len, msg_len;
EXEC SQL WHENEVER SQLERROR CONTINUE;
printf("%s\n", msg);
buf_len = sizeof (err_msg);
sqlglm(err_msg, &buf_len, &msg_len);
if (msg_len > buf_len)
msg_len = buf_len;
printf("%.*s\n", msg_len, err_msg);
deconnexion(0);
exit(1);
}
\end{verbatim}
\section*{MEMO}
\subsection*{Langage PL/SQL}
\begin{verbatim}
DECLARE
variable_PL/SQL {type SQL | nom_table.nom_colonne%TYPE | nom_table%ROWTYPE} ;
CURSOR curseur IS SELECT … ;
nom_exception EXCEPTION;
BEGIN
OPEN curseur ;
FETCH curseur INTO liste de variables ;
curseur%FOUND
CLOSE curseur ;
RAISE nom_exception ;
SELECT liste_de_sélection INTO liste de variables FROM … WHERE … ORDER BY ... ;
Variable PL/SQL := &variable_ SQLPlus
IF … THEN … [ELSE …] END IF ;
WHILE … LOOP … END LOOP ;
EXCEPTION
WHEN nom_exception THEN …;
WHEN NO_DATA_FOUND THEN … ;
WHEN OTHERS THEN … :
END ;
\end{verbatim}
\subsection*{Langage PRO*C}
\begin{verbatim}
struct {long sqlcode;/* code resultant de l'exécution
=0 -> ok,
>0 -> ok avec un code d'état,
<0 -> erreur */
struct {
unsigned short sqlerrml;/*longueur du message*/
char sqlerrmc[70];/*message d'erreur*/
} sqlerrm;
long sqlerrd[6];/* seul sqlerrd[2] est utilisé -> donne le nombre de lignes modifiées
UPDATE ou rajoutées par INSERT ou ramenées par un SELECT*/
char sqlwarn[8];/*sqlwarn[0] 'W -> warning*/
sqlwarn[0] = '' /*-> pas de warning*/
sqlwarn[1] = 'W'/*-> troncation numérique ou char*/
sqlwarn[2] = 'W'/*-> valeur Null est ignore */
sqlwarn[3] = 'W'/*-> plus de champs dans SELECT que de variables pour recevoir*/
sqlwarn[4] = 'W'/*-> toutes les lignes d'une table sont touchées (par DELETE ou
UPDATE par exemple)*/
sqlwarn[5] /* inutilisé */
sqlwarn[6] = 'W'/*-> Oracle a dû exécuter un rollback */
sqlwarn[7] = 'W'/*-> la donnée ramenée par un FETCH a été modifié
depuis que la clause SELECT a été executé */
} sqlca;
:var_hote INDICATOR :indicateur
:var_hote :indicateur
\end{verbatim}
%\includepdf[pages=-]{MEMO.pdf}
\end{document}