|
|
\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 2018-2019 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 Aucun document autoris\'e \hfill~\\
|
|
|
|
|
|
\end{center}
|
|
|
|
|
|
\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] (30 points)
|
|
|
Le MLD ci-dessus stocke les donn\'ees des matchs NBA.
|
|
|
|
|
|
\begin{enumerate}
|
|
|
\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 lors d'un match de sa
|
|
|
carri\`ere. La solution propos\'ee doit mettre en place deux
|
|
|
m\'ecanismes un avec et un 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 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}
|
|
|
}
|
|
|
|
|
|
|
|
|
\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)) ;
|
|
|
|
|
|
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{enumerate}
|
|
|
|
|
|
\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}[Pro C] (45 points)
|
|
|
\begin{enumerate}
|
|
|
\item (30 points) En utilisant les curseurs, \'ecrire un programme
|
|
|
Pro C qui permet d'afficher le nom et pr\'enom des membres du
|
|
|
personnel par hopital en indiquant pour chacun le nombre de
|
|
|
patients suivis et par ordre alphab\'etique des pr\'enoms ayant la
|
|
|
forme suivante : \\
|
|
|
|
|
|
\begin{SaveVerbatim}{Affichage}
|
|
|
Personnels de l’hopital XXXXX :
|
|
|
1) Nom : XXXXXX Prenom : XXXXX Salaire: XXXXX Nombre de patients : ZZ
|
|
|
2) Nom : XXXXXX Prenom : XXXXX Salaire: XXXXX Nombre de patients : ZZ
|
|
|
3) Nom : XXXXXX Prenom : XXXXX Salaire: XXXXX Nombre de patients : ZZ
|
|
|
...
|
|
|
Nombre de patients total sur l'hopital : ZZ1
|
|
|
Nombre de personnels total sur l'hopital : ZZ2
|
|
|
|
|
|
Personnels de l’hopital XXXXX :
|
|
|
1) Nom : XXXXXX Prenom : XXXXX Salaire: XXXXX Nombre de patients : ZZ
|
|
|
2) Nom : XXXXXX Prenom : XXXXX Salaire: XXXXX Nombre de patients : ZZ
|
|
|
3) Nom : XXXXXX Prenom : XXXXX Salaire: XXXXX Nombre de patients : ZZ
|
|
|
...
|
|
|
Nombre de patients total sur l'hopital : ZZ1
|
|
|
Nombre de personnels total sur l'hopital : ZZ2
|
|
|
...
|
|
|
\end{SaveVerbatim}
|
|
|
|
|
|
% \cache{%\begin{small}
|
|
|
\BUseVerbatim{Affichage}
|
|
|
%\end{small}
|
|
|
% }
|
|
|
|
|
|
Sachant que la valeur de \code{salaire} peut ne pas \^etre
|
|
|
renseignée, il faudra donc g\'erer ce cas.
|
|
|
\item (15 points) \'Ecrire un programme Pro C qui permet d'ins\'erer un nouveau
|
|
|
membre du personnel. Les valeurs saisies par l'utilisateurs seront
|
|
|
ins\'er\'ees dans la table \code{PERSONNEL}.
|
|
|
\begin{itemize}
|
|
|
\item V\'erifier que la fonction existe d\'ej\`a ainsi que l'hopital.
|
|
|
\item
|
|
|
V\'erifier aussi que l'\code{id\_personnel} n'existe pas d\'ej\`a, s'il
|
|
|
existe alors afficher les caract\'eristiques du personnel existant.
|
|
|
\end{itemize}
|
|
|
%% \item 'Ecrire un programme Pro C qui permet de renter une nouvelle
|
|
|
%% affectation entre un patient et un membre du pesonnel. V\'erifier
|
|
|
%% que le patient et le personel existent d\'ej\`a.
|
|
|
|
|
|
|
|
|
\begin{SaveVerbatim}{questionune}
|
|
|
int main(int argc, char** argv){
|
|
|
varchar vnom[20];
|
|
|
varchar vprenom[20];
|
|
|
varchar vhopital[20];
|
|
|
char vidhopital[6];
|
|
|
int fini;
|
|
|
int fin=1;
|
|
|
int vnbnom;
|
|
|
int vnbhopit;
|
|
|
int nb=1;
|
|
|
EXEC SQL WHENEVER SQLERROR DO sql_error("Oracle error\n");
|
|
|
printf("\n Appel de la fonction connexion");
|
|
|
connexion();
|
|
|
printf("\n Appel de la fonction deconnexion");
|
|
|
EXEC SQL WHENEVER SQLERROR DO sql_error("Oracle error\n");
|
|
|
EXEC SQL SELECT p.Nom, p.Prenom, h.Nom INTO :vnom, :vprenom, :vhopital
|
|
|
FROM PERSONNEL p, HOPITAL h
|
|
|
WHERE h.id_hopital = p.id_hopital and p.id_personnel='PE01';
|
|
|
vnom.len=strlen(vnom.arr);
|
|
|
vprenom.len=strlen(vprenom.arr);
|
|
|
vhopital.len=strlen(vhopital.arr);
|
|
|
printf("\n TEST pour PE01 : Nom : %.*s prenom : %.*s hopital : %.*s \n"
|
|
|
, vnom.len, vnom.arr, vprenom.len, vprenom.arr, vhopital.len,vhopital.arr);
|
|
|
printf("\n Affichage les hopitaux \n");
|
|
|
EXEC SQL SELECT COUNT(h.Nom) INTO :vnbhopit FROM HOPITAL h;
|
|
|
printf("\nNombre d'hopitaux est %d\n",vnbhopit);
|
|
|
EXEC SQL DECLARE hopitaux CURSOR FOR SELECT Nom, id_hopital
|
|
|
FROM HOPITAL ORDER by Nom;
|
|
|
EXEC SQL OPEN hopitaux;
|
|
|
EXEC SQL FETCH hopitaux INTO :vhopital, :vidhopital;
|
|
|
if (sqlca.sqlcode == 1403) {fin = 0;}
|
|
|
while (fin!=0) {
|
|
|
vhopital.len=strlen(vhopital.arr);
|
|
|
printf("\n Affichage des personnels de l'hopital %.*s : \n",
|
|
|
vhopital.len,vhopital.arr);
|
|
|
EXEC SQL SELECT COUNT(Nom) INTO :vnbnom FROM PERSONNEL
|
|
|
WHERE id_hopital = :vidhopital;
|
|
|
printf("\nNombre de personnel de l'hopital %.*s est %d\n",
|
|
|
vhopital.len,vhopital.arr, vnbnom);
|
|
|
EXEC SQL DECLARE personnels CURSOR FOR SELECT Nom, Prenom FROM PERSONNEL WHERE id_hopital = :vidhopital ORDER by prenom;
|
|
|
EXEC SQL OPEN personnels;
|
|
|
fini=1;
|
|
|
EXEC SQL FETCH personnels INTO :vnom, :vprenom;
|
|
|
if (sqlca.sqlcode == 1403) {fini = 0;}
|
|
|
while (fini!=0){
|
|
|
vnom.len=strlen(vnom.arr);
|
|
|
vprenom.len=strlen(vprenom.arr);
|
|
|
printf("%d) Nom : %.*s Prenom : %.*s \n",
|
|
|
nb, vnom.len, vnom.arr, vprenom.len, vprenom.arr);
|
|
|
nb++;
|
|
|
EXEC SQL FETCH personnels INTO :vnom, :vprenom;
|
|
|
if (sqlca.sqlcode == 1403) {fini = 0;} }
|
|
|
EXEC SQL CLOSE personnels;
|
|
|
EXEC SQL FETCH hopitaux INTO :vhopital, :vidhopital;
|
|
|
if (sqlca.sqlcode == 1403) {fin = 0;}
|
|
|
}
|
|
|
printf(" Fini \n");
|
|
|
EXEC SQL CLOSE hopitaux;
|
|
|
deconnexion(1);
|
|
|
return(0);
|
|
|
}
|
|
|
\end{SaveVerbatim}
|
|
|
|
|
|
\cache{\begin{small}
|
|
|
\BUseVerbatim{questionune}
|
|
|
\end{small}
|
|
|
}
|
|
|
|
|
|
\begin{SaveVerbatim}{Insertion}
|
|
|
int main(int argc, char** argv){
|
|
|
char vidperso[20];
|
|
|
char vidfonction[20];
|
|
|
char vidhopital[6];
|
|
|
VARCHAR vnom[20];
|
|
|
VARCHAR vprenom[20];
|
|
|
char eidperso[20];
|
|
|
char eidfonction[20];
|
|
|
char eidhopital[6];
|
|
|
VARCHAR enom[20];
|
|
|
VARCHAR eprenom[20];
|
|
|
int nbhopital=0;
|
|
|
int nbfonction=0;
|
|
|
int nbperso=1;
|
|
|
EXEC SQL WHENEVER SQLERROR DO sql_error("Oracle error\n");
|
|
|
printf("\n Appel de la fonction connexion");
|
|
|
connexion();
|
|
|
printf("\n Appel de la fonction deconnexion");
|
|
|
EXEC SQL WHENEVER SQLERROR DO sql_error("Oracle error\n");
|
|
|
printf("Saisir un nouveau personnel \n");
|
|
|
printf("Entrer son nom : ");
|
|
|
scanf("%s",vnom.arr);
|
|
|
vnom.len=strlen(vnom.arr);
|
|
|
printf("Entrer son prenom : ");
|
|
|
scanf("%s",vprenom.arr);
|
|
|
vprenom.len=strlen(vprenom.arr);
|
|
|
|
|
|
do{
|
|
|
printf("Entrer son id hopital : ");
|
|
|
scanf("%s",vidhopital);
|
|
|
EXEC SQL SELECT COUNT(*) INTO :nbhopital FROM HOPITAL WHERE id_hopital=:vidhopital;
|
|
|
//printf("nbhopital %d\n",nbhopital);
|
|
|
}
|
|
|
while (nbhopital !=1);
|
|
|
do{
|
|
|
printf("Entrer son id personnel : ");
|
|
|
scanf("%s",vidperso);
|
|
|
EXEC SQL SELECT COUNT(*) INTO :nbperso FROM PERSONNEL WHERE id_personnel=:vidperso;
|
|
|
if (nbperso==1){
|
|
|
printf("Ce numero de personnel existe deja\n");
|
|
|
EXEC SQL SELECT * INTO :eidperso, :eidfonction, :eidhopital, :enom, :eprenom
|
|
|
FROM PERSONNEL WHERE id_personnel=:vidperso;
|
|
|
printf("ID PERSO : %s \n",eidperso);
|
|
|
printf("ID FONCTION : %s \n",eidfonction);
|
|
|
printf("ID HOPITAL : %s \n",eidhopital);
|
|
|
printf("NOM : %s \n",enom.arr);
|
|
|
printf("PRENOM : %s \n",eprenom.arr);
|
|
|
}
|
|
|
}
|
|
|
while (nbperso !=0);
|
|
|
do{
|
|
|
printf("Entrer son id fonction : ");
|
|
|
scanf("%s",vidfonction);
|
|
|
EXEC SQL SELECT COUNT(*) INTO :nbfonction FROM FONCTION
|
|
|
WHERE id_fonction=:vidfonction;
|
|
|
}
|
|
|
while (nbfonction !=1);
|
|
|
EXEC SQL INSERT INTO PERSONNEL VALUES(:vidperso,:vidfonction,:vidhopital,:vnom,:vprenom);
|
|
|
EXEC SQL COMMIT;
|
|
|
deconnexion(1);
|
|
|
return(0);}
|
|
|
\end{SaveVerbatim}
|
|
|
|
|
|
\cache{\begin{small}
|
|
|
\BUseVerbatim{Insertion}
|
|
|
\end{small}
|
|
|
}
|
|
|
|
|
|
\end{enumerate}
|
|
|
\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}
|