diff --git a/COURS/PLSQL.tex b/COURS/PLSQL.tex index 4a6d6d1..30918d2 100644 --- a/COURS/PLSQL.tex +++ b/COURS/PLSQL.tex @@ -855,6 +855,11 @@ DROP TABLEl Tligne; \end{exemple} \section{Gestion des erreurs : \code{EXCEPTION ... WHEN ... THEN}} + +Lorsqu'une instruction se passe mal en \plsql, une \emph{exception} +est lev\'ee. Il est possible de sp\'ecifier une comportement adpat\'e +dans ce cas dans la section \code{EXCEPTION}. + \subsection{La section \code{EXCEPTION}} La section \code{EXCEPTION} permet d'affecter un traitement approprié @@ -868,9 +873,11 @@ Les types d'erreurs sont les suivants : \begin{exemple} Les résultats à afficher sont placés dans -une table \code{Tligne}. +une table \code{Tligne}. Lorsque la requ\^ete \sql{} ne produit pas de +r\'esultats alors une exception est lev\'ee. \begin{verbatim} +drop table Tligne; create table Tligne (Tligne varchar2(150)); variable vnoproduit char(4) prompt taper la référence du produit à rechercher : @@ -891,12 +898,11 @@ insert into Tligne values ('Désignation: ' || ddesignation); exception when no_data_found then - insert into Tligne values ( dmessage); + insert into Tligne values (dmessage); end ; . / select * from Tligne; -drop table Tligne; \end{verbatim} \end{exemple} @@ -904,25 +910,33 @@ drop table Tligne; \end{remarque} \begin{exercice} - Enregistrer une livraison pour un produit donné : + Enregistrer une livraison pour un produit donné : \begin{itemize} -\item saisie du numéro de produit et de la quantité livrée, -\item accès au stock du produit : exception ‘\code{référence inconnue}’, -\item calcul du nouveau stock et mise à jour du stock. +\item saisie du numéro de produit et de la quantité livrée, +\item accès au stock du produit : exception si ‘\code{référence inconnue}’, +\item calcul du nouveau stock et mise à jour du stock. \end{itemize} \end{exercice} +%% \cache{ +%% TODO +%% } + \begin{exercice} Enregistrer un nouveau produit d’un fournisseur : \begin{itemize} \item saisie des références du produit et du fournisseur, du prix fournisseur, \item accès au produit pour vérifier qu’il existe, \item accès au fournisseur pour vérifier qu’il existe, -\item accès à la liaison produit-fournisseur pour vérifier qu’elle n’est pas déjà enregistrée, +\item accès à la liaison produit-fournisseur pour vérifier qu’elle n’est pas déjà enregistrée (Exception \`a g\'erer), \item enregistrement de la liaison. \end{itemize} \end{exercice} +%% \cache{ +%% TODO +%% } + \subsection{Erreur Oracle} @@ -1008,29 +1022,87 @@ END; \end{verbatim} \end{exemple} -\begin{exercice} Mise en évidence des exceptions \verb+TOO_MANY_ROWS, OTHERS+ - -Pour mettre en évidence l’exception \verb+TOO_MANY_ROWS+, créez un -fichier de commandes \sql{} qui: demande un numéro de fournisseur, accède -aux N° des produits de ce fournisseur (par \code{select into}) retourne le -message ‘\code{le fournisseur n’a pas de produit}’ ou ‘\code{le fournisseur a plusieurs -produits}’, ou le N° du produit s’il n’en a qu’un. - +\begin{exercice} Pour mettre en évidence l’exception \verb+TOO_MANY_ROWS+, créez un fichier de commandes \sql{} qui: + \begin{itemize} + \item demande un numéro de fournisseur, + \item accède aux N° des produits de ce fournisseur (par \code{select into}) + \item retourne le message ‘\code{le fournisseur n’a pas de produit}’ ou +‘\code{le fournisseur a plusieurs produits}’, ou le N° du produit s’il +n’en a qu’un. + \end{itemize} Le résultat sera placé dans une table \code{TLIGNE (LIGNE - varchar2(200))} Placez aussi dans cette table le \code{SQLCODE} et -le message Oracle obtenus à l’issue de \code{SELECT}. + varchar2(200))}. Placez aussi dans cette table le \code{SQLCODE} et +le message Oracle obtenus à l’issue de \code{SELECT}. Modifiez le +programme en remplaçant une des deux exceptions par \code{OTHERS}. +\end{exercice} + + + +\subsection{Erreur utilisateur : \code{EXCEPTION, RAISE}} + +Le traitement de l’anomalie doit être déclenché en passant dans la +partie \code{EXCEPTION} par \code{RAISE}. +\begin{verbatim} +DECLARE +... +nom_erreur EXCEPTION; +... +BEGIN +... +IF anomalie +THEN RAISE nom_erreur; +... +EXCEPTION +WHEN nom_erreur THEN +traitement à effectuer en cas d’anomalie; +END; +\end{verbatim} + +Sortie du bloc après exécution du traitement. + +\begin{exemple} +Accèder au stock d’un produit de Numéro donné avec Erreur Oracle quand +le produit n’existe pas et Erreur utilisateur quand le stock est +nul. Les anomalies sont placées dans une table \code{terreur(z1 + varchar2(30), z2 varchar2(30))} + +\begin{verbatim} +DECLARE +... +stock_nul EXCEPTION; +dstock number; +... +BEGIN +SELECT stock INTO dstock FROM tproduit WHERE noproduit = ‘&vnoproduit’; +IF stock = 0 +THEN RAISE stock_nul; +traitement quand le stock n’est pas nul... +EXCEPTION +WHEN NO_DATA_FOUND THEN +INSERT INTO terreur VALUES (‘&vnoproduit’, ‘produit inconnu’); +WHEN stock_nul THEN +INSERT INTO terreur VALUES (‘&vnoproduit’, ‘stock nul’); +END; +\end{verbatim} +\end{exemple} -Modifiez le programme en remplaçant une des deux exceptions par \code{OTHERS}. +\begin{exercice} Pour remplacer l’erreur Oracle par une erreur utilisateur, compter le nombre de produits ayant le numéro donné et déclencher une exception si ce nombre est nul. \end{exercice} + \section{Les curseurs}\label{sec:curseur} -\subsection{\code{DECLARE, OPEN, FETCH, CLOSE}} Lorsqu’une requête \code{SELECT} est susceptible de délivrer plusieurs -lignes, on associe à celle ci un «curseur explicite» qui va -permettre d’accéder aux lignes du résultat. L’algorithme est analogue -au traitement d’un fichier séquentiel. +lignes, on associe à celle ci un «curseur explicite» qui va permettre +d’accéder aux lignes du résultat. L’algorithme est analogue au +traitement d’un fichier séquentiel. + +\subsection{\code{DECLARE, OPEN, FETCH, CLOSE}} +Il faut d'abord d\'eclarer le curseur dans le bloc \code{DECLARE}, +ensuite ouvrir le curseur avec la commande \code{OPEN} et penser \`a +le ferm\'e une fois celui-ci utilis\'e. Pour acc\'eter aux donn\'ees +les unes apr\`es les autres il faut utiliser la commande \code{FETCH}. \begin{exemple} Traitement des rayons d’un étage donné. @@ -1057,21 +1129,21 @@ END; \end{verbatim} \end{exemple} -\begin{exercice} Pourcentage de produits ayant un stock nul (une solution avec curseur et une sans). +\begin{exercice} Caculer le pourcentage de produits ayant un stock nul. Proposer une solution avec curseur et une sans. \end{exercice} -\begin{exercice} Créer une table des produits classés par valeur du stock : No de produit, désignation, valeur du stock, classement. +\begin{exercice} Créer une table des produits classés par valeur du stock : No de produit, désignation, valeur du stock, classement. \end{exercice} \begin{exercice} Créer une table des produits qui n’ont pas de fournisseur et une table des produits qui en ont avec les noms de leurs fournisseurs. \end{exercice} + \subsection{\code{UPDATE, DELETE ... WHERE CURRENT OF curseur}} -Lors du parcours d'une table (ou une vue modifiable) par -\code{FETCH} à l’aide d’un curseur, il est possible de demander à mettre à jour -ou supprimer la ligne courante par la condition \code{WHERE CURRENT - OF} nom du curseur. Le curseur doit avoir été déclaré \code{FOR - UPDATE} +Lors du parcours d'une table (ou une vue modifiable) par \code{FETCH} +à l’aide d’un curseur, il est possible de demander à mettre à jour ou +supprimer la ligne courante par la condition \code{WHERE CURRENT OF} +nom du curseur. Le curseur doit avoir été déclaré \code{FOR UPDATE} \begin{verbatim} CURSOR r IS @@ -1088,61 +1160,10 @@ COMMIT; entre deux exécutions qui voudraient écrire dans la même table. \begin{exercice} - augmenter de 10\% les produits de plus de 1000\euro{}, et de 5\% les autres. -\end{exercice} - -Erreur utilisateur : \code{EXCEPTION, RAISE} - -Le traitement de l’anomalie doit être déclenché en passant dans la -partie \code{EXCEPTION} par \code{RAISE}. -\begin{verbatim} -DECLARE -... -nom_erreur EXCEPTION; -... -BEGIN -... -IF anomalie -THEN RAISE nom_erreur; -... -EXCEPTION -WHEN nom_erreur THEN -traitement à effectuer en cas d’anomalie; -END; -\end{verbatim} - -Sortie du bloc après exécution du traitement. - -\begin{exemple} -Accèder au stock d’un produit de Numéro donné avec Erreur Oracle quand -le produit n’existe pas et Erreur utilisateur quand le stock est -nul. Les anomalies sont placées dans une table \code{terreur(z1 - varchar2(30), z2 varchar2(30))} - -\begin{verbatim} -DECLARE -... -stock_nul EXCEPTION; -dstock number; -... -BEGIN -SELECT stock INTO dstock FROM tproduit WHERE noproduit = ‘&vnoproduit’; -IF stock = 0 -THEN RAISE stock_nul; -traitement quand le stock n’est pas nul... -EXCEPTION -WHEN NO_DATA_FOUND THEN -INSERT INTO terreur VALUES (‘&vnoproduit’, ‘produit inconnu’); -WHEN stock_nul THEN -INSERT INTO terreur VALUES (‘&vnoproduit’, ‘stock nul’); -END; -\end{verbatim} -\end{exemple} - -\begin{exercice} Pour remplacer l’erreur Oracle par une erreur utilisateur, compter le nombre de produits ayant le numéro donné et déclencher une exception si ce nombre est nul. + \'Ecrire un code \plsql{} qui augmenter de 10\% les produits de plus + de 1000\euro{}, et de 5\% les autres. \end{exercice} - \newpage \begin{figure}[htb]