You are on page 1of 27

Introduction aux Procdures Stockes dInterbase

Ecrit par Etienne Bar, dveloppeur et formateur indpendant et membre de lquipe de www.developpez.com. Reproduction, copie, publication sur un autre site Web interdite sans autorisation de l'auteur

Avant Propos........................................................................................................................2 Introduction : Pourquoi les procdures stockes ? ...................................................................2 La premire procdure stocke...............................................................................................3 1) Cration de la procdure stocke...................................................................................3 2) Suppression dune procdure stocke.............................................................................4 3) Utilisation dune procdure stocke................................................................................4 Rgles de base pour crire une Procdure Stocke ...................................................................6 1) Partie Dclarative.........................................................................................................7 Paramtre dentre ....................................................................................................7 Paramtre de sortie ...................................................................................................7 2) Partie procdurale........................................................................................................9 Laffectation..............................................................................................................9 Les oprations arithmtiques .................................................................................... 10 Concatnation de chanes de caractres..................................................................... 11 Utilisation de fonctions ............................................................................................. 11 Transtypage ........................................................................................................... 12 1) Utilisation des variables et des paramtres ................................................................... 12 Instructions disponibles ....................................................................................................... 14 1) Litration et la condition. ........................................................................................... 15 Itration avec WHILEDO........................................................................................ 15 Condition avec IF THEN ELSE ............................................................................. 16 Renvoi dinformations avec Suspend .......................................................................... 17 2) Utilisation de commandes SQL .................................................................................... 19 Select..................................................................................................................... 19 Update, Insert, Delete.............................................................................................. 20 Mise jour de donnes renvoyes par un select ......................................................... 23 Excution de procdures stockes ............................................................................. 24 3) Terminer une procdure stocke avant la dernire instruction......................................... 24 Fin dexcution avec EXIT......................................................................................... 24 Gestion derreurs avec la commande Exception........................................................... 24 Documentation officielle sur les procdures stockes .............................................................. 26 En conclusion ..................................................................................................................... 26 Annexe 1 : Schma de la base employee ............................................................................... 27

Etienne Bar Dveloppeur et formateur indpendant http://www.sampathdev.com/ Page 1/27

Avant Propos
Le cours qui suit sapplique Interbase V 6.0.1. Le fonctionnement nest pas garanti avec Interbase 7.0 et Firebird. Mais connaissant la bonne compatibilit ascendante de ces deux logiciels, je pense que ce qui suit devrait parfaitement fonctionner. Vos remarques ce sujet sont les bienvenues. Les exemples de ce cours sont effectus sur la base employee, fournie normalement avec Interbase. Le schma de cette base est fourni en annexe 1 (Sous Windows avec une installation classique, elle se trouve dans le rpertoire C:\Program Files\Borland\InterBase\Examples\Database) La comprhension de ce tutorial implique de connatre les bases de la programmation (notion de variable, de paramtres, ditration, de condition) et celles du sql (allez donc faire un tour sur http://sqlpro.developpez.com/) Je remercie particulirement Frdric Huet (Barbibulle) pour toutes les fois o il ma dpann et pour sa relecture attentive de ce tutoriel. Sans lui, les procdures stockes seraient restes fort mystrieuses pour moi. Merci galement Jean-Marc Rabilloud pour ses remarques constructives. Nhsitez pas me faire part de vos remarques et commentaires pour amliorer ce cours.

Introduction : Pourquoi les procdures stockes ?


Une procdure stocke est, comme son nom lindique, une procdure manipulant des donnes1 crite dans un langage procdural souvent spcifique au SGBD qui est stocke dans la base de donnes.

Une procdure stocke est plus rapide utiliser : Elle utilise la puissance du serveur, gnralement mieux pourvu que le poste client. Elle soulage le trafic rseau puisque tout le traitement se fait sur le serveur. Seule la requte navigue du client vers le serveur et le rsultat, si besoin, du serveur vers le client Cest un mode de partage des tches dun dveloppement. On peut ainsi crire les code de traitement des donnes dans la base puis (ou paralllement) lIHM dans son langage prfr. Linconvnient dcrire du code mtier au cur de la base de donnes est videmment que lapplication nest plus indpendante du SGBD mais prsente des avantages de performance certains (essayez, vous nen reviendrez pas). Un autre avantage est que la mise jour dune procdure stocke permet tous les clients2 de la base de donnes, quels quils soient (Client-Serveur, Web, etc), de bnficier de cette mise jour. Exemple, jcris une procdure stocke pour connatre le prix dun article dans une gestion commerciale. Si les rgles changent, je modifie cette procdure stocke et tous les clients de lapplication en bnficient. Si les paramtres dappel et de sortie de la procdure stocke ne changent pas, mes clients nont mme pas besoin dtre modifis.

Il est parfaitement concevable dimaginer une procdure stocke qui ne manipule pas de donnes de la base. Mais javoue avoir du mal sur les applications pratiques dune telle procdure stocke. 2 Comprendre client au sens dobjet logiciel qui utilise ma base et non comme quelquun qui machte quelque chose Etienne Bar Dveloppeur et formateur indpendant http://www.sampathdev.com/ Page 2/27

La premire procdure stocke


1) Cration de la procdure stocke

Nous dsirons connatre le nombre demploys et le nombre de ceux pour lesquels la colonne phone-ext est renseigne. Le SQL qui va nous permettre dcrire ceci est : SELECT COUNT(PHONE_EXT), COUNT(EMP_NO) FROM EMPLOYEE ; Et interbase, dans sa grande bont et avec sa clrit habituelle, nous rpond :

Si nous voulons stocker ce traitement sous la forme dune procdure stocke, nous crirons donc dans ISQL : Set term ^ ; CREATE PROCEDURE MA_PREMIERE_PS RETURNS ( NBRETEL INTEGER, NBREEMP INTEGER) AS BEGIN SELECT COUNT(PHONE_EXT), COUNT(EMP_NO) FROM EMPLOYEE INTO :NBRETEL, :NBREEMP; SUSPEND; END ^ Set term ;^

Ce qui prcde mrite quelques explications : Set term ^ ; Afin que les points-virgules qui parsment notre procdure ne soient pas interprts comme un sparateur de deux instructions SQL , il faut indiquer Interbase que le sparateur ne sera plus le point virgule mais le ^. Dans le cas contraire, nous obtiendrons le message : Dynamic SQL Error SQL error code = -104 Unexpected end of command Indiquant quInterBase a quelques difficults sy retrouver.

Etienne Bar Dveloppeur et formateur indpendant http://www.sampathdev.com/ Page 3/27

Nous crivons ensuite notre procdure stocke. Lcriture doit tre vue comme une seule et mme instruction SQL, do lintrt de linstruction qui prcde. La fin de linstruction se fait par le nouveau sparateur ^. Enfin, linstruction Set term ;^ Remet le point virgule comme sparateur. Intressons nous maintenant la dfinition de la PROCDURE STOCKE proprement dite : Linstruction CREATE PROCEDURE MA_PREMIERE_PS ... Entrane la cration dun nouvel objet dans la base. A noter que linstruction la plus courte pour crer une procdure stocke serait : Set term ^ ; CREATE PROCEDURE FAIT_RIEN AS BEGIN EXIT ; END ^ Set term ;^ qui cre une procdure stocke qui ne fait absolument rien.

2)

Suppression dune procdure stocke

La suppression dune procdure stocke se fera par linstruction : DROP PROCEDURE FAIT_RIEN Instruction qui ne russira que si la procdure stocke Fait_rien nest pas utilise ailleurs dans la base dans une autre procdure stocke par exemple-, car InterBase conserve dans ces tables systme la rfrence de toutes les procdures stockes (et de tous les autres objets) utiliss

3)

Utilisation dune procdure stocke


SELECT Champ1, Champ2, etc FROM NomdelaProcdureStocke

Lutilisation dune procdure stocke qui renvoie des valeurs se fait par linstruction :

Ou champ1 et champ2 correspondent des paramtres de retour de la procdure stocke. Il est noter que linstruction select * from fait_rien SQL error code = -84 procedure FAIT_RIEN does not return any values ce qui sexplique puisque la procdure stocke ne renvoie aucune valeur. A linverse, linstruction select nbretel, nbreemp from ma_premiere_ps renvoie bien un rsultat correct.

Etienne Bar Dveloppeur et formateur indpendant http://www.sampathdev.com/ Page 4/27

Si cette procdure utilise des paramtres, on les spcifiera entre parenthses, spars par des virgules select nbretel, nbreemp from ma_premiere_ps(1,2) Pour utiliser une procdure stocke qui fait des traitements mais ne renvoie rien, on pourra utiliser linstruction Execute procedure NomdelaProcdureStocke Qui excutera les instructions de la procdure stocke sans rien renvoyer3 Si cette procdure utilise des paramtres, on les spcifiera SANS parenthses aprs le nom de la procdure, spars par des virgules Execute procedure NomdelaProcdureStocke 1,2

A moins dutiliser Returning Values Etienne Bar Dveloppeur et formateur indpendant http://www.sampathdev.com/ Page 5/27

Rgles de base pour crire une Procdure Stocke


On peut utiliser toutes les instructions de manipulation de donnes (Select, Insert, Update, Delete) mais lutilisation de langage de dfinition de donnes (Create, Alter) pour modifier la structure de la base nest pas possible dans une procdure stocke On ne peut pas utiliser de domaines dans les dfinitions de paramtres et de variables La commande SET Generator nest pas utilisable dans une procdure stocke. Les variables doivent toujours tre dclares (soient comme paramtres dentre, de sortie ou de variables) Les instructions sont spares par des points-virgules (BEGIN et END ne sont pas des instructions) Le code dune procdure stocke commence par une partie dclarative et est suivi par une partie procdurale situe entre un Begin et un End. Les commentaires doivent tre places entre /* */. Un commentaire ouvert doit tre ferm Le retour la ligne nest pas une fin dinstruction On ne peut pas faire de SQL Dynamique (ce qui, ce quon ma dit, serait possible dans Firebird 1.5)

Cette partie utilise comme exemple la procdure stocke DEPT_BUDGET (qui se trouve dans la base Employee) et qui est la suivante : CREATE PROCEDURE DEPT_BUDGET ( DNO CHAR (3)) RETURNS ( TOT NUMERIC (18, 2)) AS DECLARE VARIABLE sumb DECIMAL(12, 2); DECLARE VARIABLE rdno CHAR(3); DECLARE VARIABLE cnt INTEGER; BEGIN tot = 0; SELECT budget FROM department WHERE dept_no = :dno INTO :tot; SELECT count(budget) FROM department WHERE head_dept = :dno INTO :cnt; IF (cnt = 0) THEN SUSPEND; FOR SELECT dept_no FROM department WHERE head_dept = :dno INTO :rdno DO BEGIN EXECUTE PROCEDURE dept_budget :rdno RETURNING_VALUES :sumb; tot = tot + sumb; END SUSPEND; END

Etienne Bar Dveloppeur et formateur indpendant http://www.sampathdev.com/ Page 6/27

1)

Partie Dclarative

Cette partie est appele header dans la documentation officielle dInterbase Examinons lentte de la CREATE PROCEDURE DEPT_BUDGET ( DNO CHAR (3)) RETURNS ( TOT NUMERIC (18, 2)) AS DECLARE VARIABLE sumb DECIMAL(12, 2); DECLARE VARIABLE rdno CHAR(3); DECLARE VARIABLE cnt INTEGER; Cette procdure stocke a un paramtre dentre (DNO) dfini en CHAR(3) et renvoie la valeur TOT dfini en NUMERIC (18,2) Pour la dfinition des types de donnes, je vous renvoie au chapitre Specifying Datatypes du data dfinition guide de la documentation dInterBase. On a ensuite trois variables qui vont tre utilises dans la partie procdurale

Paramtre dentre
Un paramtre dentre est une information ncessaire au traitement de la procdure stocke. Par exemple, la procdure stocke cit plus haut prend un numro de dpartement en paramtre, numro quelle va utiliser pour slectionner les donnes ncessaires au calcul.

Paramtre de sortie
Les paramtres de sortie sont les informations que renvoie la procdure stocke lappelant aprs traitement. A linverse dune fonction ou dune procdure crite dans un langage de programmation traditionnel (Pascal, C, Visual Basic), les paramtres de sortie peuvent tre renvoys plusieurs fois avec des valeurs diffrentes. Je vous invite consulter le paragraphe Renvoi dinformations avec Suspend page 17 pour mieux comprendre quoi correspond et comment les paramtres de sortie dans une procdure stocke.

Etienne Bar Dveloppeur et formateur indpendant http://www.sampathdev.com/ Page 7/27

Il est tout fait possible dcrire une procdure stocke qui ne prend pas de paramtres et ne renvoie rien non plus. CREATE PROCEDURE PROC_SANS_PARAMETRES AS DECLARE VARIABLE sumb DECIMAL(12, 2); DECLARE VARIABLE rdno CHAR(3); DECLARE VARIABLE cnt INTEGER; Si on utilise plusieurs paramtres, ceux ci sont spars par des virgules. CREATE PROCEDURE BLIN_INTERROGELIVRAISONS ( TYPO INTEGER, SELECTIONARTICLES INTEGER, FINANALYSE DATE, SITEDEPART VARCHAR (12)) RETURNS ( RES_RF_COM INTEGER, RES_RF_PRT VARCHAR (12), RES_RF_SIT VARCHAR (12), RES_DATEHEURE TIMESTAMP, RES_QTE DECIMAL (9, 3), RES_TYPEMVT VARCHAR (5)) AS Toutes les variables sont locales. La notion de variable globale nexiste pas dans InterBase. Le seul moyen de passer des donnes dune procdure une autre est dutiliser des paramtres ou de stocker ces donnes dans une table.

Etienne Bar Dveloppeur et formateur indpendant http://www.sampathdev.com/ Page 8/27

2)

Partie procdurale

Cette partie est appele body dans la documentation officielle dInterbase Le corps de la procdure commence toujours par BEGIN et se termine par END. Entre le BEGIN et le END, les instructions sont spares par des points-virgules. On ne mettra jamais de point-virgule derrire un END ou un BEGIN. Les fans de pascal/delphi doivent se mfier. Dans la mme procdure, nous trouvons : BEGIN tot = 0; SELECT budget FROM department WHERE dept_no = :dno INTO :tot; SELECT count(budget) FROM department WHERE head_dept = :dno INTO :cnt; IF (cnt = 0) THEN SUSPEND; FOR SELECT dept_no FROM department WHERE head_dept = :dno INTO :rdno DO BEGIN EXECUTE PROCEDURE dept_budget :rdno RETURNING_VALUES :sumb; tot = tot + sumb; END SUSPEND; END Pour un premier essai, nous attaquons fort car nous utilisons une procdure rcursive. Nous allons passer en revue quelques instructions lmentaires

Laffectation
Laffectation se fait laide du symbole gal (=) <Variable ou paramtre> = <Valeur ou Opration>

Etienne Bar Dveloppeur et formateur indpendant http://www.sampathdev.com/ Page 9/27

Les oprations arithmtiques


Pour les 4 oprations, on utilisera les 4 symboles traditionnels +,-,*,/ CREATE PROCEDURE TESTDECALCUL RETURNS ( TEXTE CHAR (50), NOMBRE FLOAT) AS BEGIN TEXTE = 'Une addition NOMBRE = 10 + 10 ; suspend; 10 + 10 =' ;

TEXTE = 'Une soustraction 100 - 10 =' ; NOMBRE = 100 - 10 ; suspend; TEXTE = 'Une multiplication 100 * 10 =' ; NOMBRE = 100 * 10 ; suspend; TEXTE = 'Une autre multiplication 100 - 5 * 10 =' ; NOMBRE = 100 - 5 * 10 ; suspend; TEXTE = 'Une division 100 / 10 =' ; NOMBRE = 100 / 10 ; suspend; TEXTE = 'Une autre division 100 - 5 / 10' ; NOMBRE = 100 - 5 / 10 ; suspend; END qui renvoie les valeurs suivantes

et quen dduisons nous ? quInterBase respecte lordre naturel de priorit des oprations (multiplication et division avec addition et soustraction). Bien sur, lutilisation des parenthses est dans ce cas recommande pour la lecture du code. L instruction SUSPEND, pour ceux qui ne lont pas encore devin, permet de renvoyer des donnes ce qui (une autre procdure stocke, un programme client, une instruction iSQL) appelle la procdure stocke. Chaque suspend renvoie la valeur des paramtres de sortie au moment de lappel de linstruction. Etienne Bar Dveloppeur et formateur indpendant http://www.sampathdev.com/ Page 10/27

Concatnation de chanes de caractres


Loprateur de concatnation dans les SQL dInterBase est le double | (altgr+6 sur un clavier azerty standard) Chaine1 = Developpez Chaine2 = .com Resultat = Chaine1 || Chaine2 Rsultat contiendra, vous lavez devin, la chane Developpez.com

Utilisation de fonctions
En standard, InterBase est extrmement pauvre en fonctions. A ma connaissance, les seules fonctions utilisables sont CAST pour transtyper une variable dans un autre type est dont la syntaxe est

CAST(Variable AS TypeInterBase) O TypeInterBase dsigne un type de donnes connu dInterBase (pas un domaine) Ainsi, Cast(VarEnt as DoublePrecision) transformera la variable VarEnt en rel double prcision GEN_ID pour utiliser un gnrateur UPPER pour mettre en majuscules une chane de caractres.

Lutilisation dUDF (fonctions externes) est donc fortement recommande, sinon obligatoire.

Etienne Bar Dveloppeur et formateur indpendant http://www.sampathdev.com/ Page 11/27

Transtypage
InterBase est relativement gentille et les acrobaties (daucuns diront les horreurs) du genre qui suit ne larrtent pas CREATE PROCEDURE TRANSTYPAGE RETURNS ( TEXTE CHAR (50), REEL FLOAT, ENTIER INTEGER) AS BEGIN TEXTE = '10' ; REEL = 20; ENTIER = TEXTE + REEL ; SUSPEND; END A lexcution, la procdure stocke renverra :

Par contre, il y a quand mme une justice car TEXTE = 'Un texte' ; REEL = 20; ENTIER = TEXTE + REEL ; suspend; renvoie le message derreur Conversion error from string "Un texte Que nous navons pas vol.

"

1)

Utilisation des variables et des paramtres

Soit la procdure stocke suivante : CREATE PROCEDURE VARIABLES RETURNS ( NBRE INTEGER) AS DECLARE VARIABLE DEPT_NO CHAR(3); BEGIN DEPT_NO = '600'; SELECT COUNT(*) FROM EMPLOYEE WHERE DEPT_NO = DEPT_NO INTO :NBRE ; SUSPEND ; END Excutons l, elle nous renvoie la valeur de 42, autrement dit la mme chose que Etienne Bar Dveloppeur et formateur indpendant http://www.sampathdev.com/ Page 12/27

Select count(*) from Alors que Select count(*) from Renvoie la valeur 2

EMPLOYEE EMPLOYEE where dept_no = 600

Notez que si nous crivons Select count(*) from EMPLOYEE where dept_no = dept_no Nous obtenons galement 42 : nous cherchons en effet tous les employs qui ont un dpartement gal leur dpartement, ce qui revient chercher tous les employs ou encore faire une recherche qui ne sert strictement rien ! Alors que si nous crivons et excutons : CREATE PROCEDURE VARIABLES RETURNS ( NBRE INTEGER) AS DECLARE VARIABLE DEPT_NO CHAR(3); BEGIN DEPT_NO = '600'; SELECT COUNT(*) FROM EMPLOYEE WHERE DEPT_NO = :DEPT_NO INTO :NBRE ; SUSPEND ; END Nous obtiendrons bien la valeur 2. La seule chose qui a chang entre les 2 procdures stockes et le : qui prcde le second dept_no dans la condition WHERE DEPT_NO = :DEPT_NO Qui indique que le second dept_no est considrer comme une variable et non comme la dsignation de la colonne dept_no de la table employee. Il est bien sur vident que cet exemple (pervers) nest l que pour vous viter des erreurs cruelles lavenir. Ne nommez pas vos variables comme des colonnes de la base et vous vous viterez bien des ennuis ou alors faites le en toute connaissance de cause. Il faut noter quil est parfaitement possible de modifier dans une procdure stocke des paramtres dentre. CREATE PROCEDURE VARIABLES_2 ( PARAM1 INTEGER, PARAM2 INTEGER) RETURNS ( NBRE INTEGER) AS BEGIN PARAM1 = PARAM1 + 1; PARAM2 = PARAM2 + 1; NBRE = PARAM1 + PARAM2; SUSPEND ; END Etienne Bar Dveloppeur et formateur indpendant http://www.sampathdev.com/ Page 13/27

Instructions disponibles
Le langage est dcrit dans le chapitre Working with stored procedures du manuel Data definition Guide . A cot des langages volus que nous avons lhabitude de manipuler, ce langage est pauvre. Ne nous en attristons pas, il nen sera que plus vite appris. Nous disposons de : Une Une Une Une Une Une Une instruction pour itrer : WHILE DO instruction pour renvoyer des donnes lappelant de la procdure stocke : Suspend instruction pour quitter la procdure (saute directement au END final) : EXIT instruction de condition : IF THEN ELSE instruction de lecture de donnes FOR <Instruction Select> DO instruction de gestion derreur WHEN DO instruction pour lever une exception : EXCEPTION <Nom de lexception>

Et bien sur, des instructions SQL qui suivent : Select Update Delete Insert

Nous avons vu plus haut la pauvret des fonctions dInterbase. Les commentaires sont placs entre les symboles /* et */. Il va de soi que ne pas commenter ses procdures ne procure quun gain de temps minimal que vous paierez au centuples dans quelque temps (vous ne pourrez pas dire quon ne vous a pas prvenu) /* Cette ligne est un commentaire */ /* Ces deux l galement */

Etienne Bar Dveloppeur et formateur indpendant http://www.sampathdev.com/ Page 14/27

1)

Litration et la condition.

Itration avec WHILEDO


Attention, les itrations qui permettent de traiter successivement les lignes renvoyes par une instruction Select sont traites avec une instruction FOR (voir un peu plus loin dans la partie utilisation de SQL) La syntaxe de cette instruction est la suivante : WHILE <Condition> DO BEGIN <Instruction 1> ; <Instruction 2> ; <Instruction n> ; END CREATE PROCEDURE ITERATION ( NOMBRE INTEGER) RETURNS ( VALEUR INTEGER) AS BEGIN VALEUR = 0 ; WHILE (VALEUR < NOMBRE) DO BEGIN VALEUR = VALEUR + 3; END SUSPEND; END La procdure qui prcde permet par exemple de trouver le premier multiple de 3 suprieur ou gal au nombre pass en paramtre. Notez que cette procdure stocke pourrait scrire ainsi : CREATE PROCEDURE ITERATION ( NOMBRE INTEGER) RETURNS ( VALEUR INTEGER) AS BEGIN VALEUR = 0 ; WHILE (VALEUR < NOMBRE) DO VALEUR = VALEUR + 3; SUSPEND; END Car il ny a quune seule instruction dans litration. On ne doit utiliser BEGIN et END que lorsquon a plusieurs instructions. Les mettre systmatiquement est nanmoins une bonne ide car cela permet de mieux comprendre la procdure. Etienne Bar Dveloppeur et formateur indpendant http://www.sampathdev.com/ Page 15/27

Ainsi, les lignes qui suivent : WHILE (VALEUR < NOMBRE) DO BEGIN VALEUR = VALEUR + 3; VALEUR = VALEUR + 1; END Ajoutent 4 la variable valeur chaque itration Alors que celles-ci : WHILE (VALEUR < NOMBRE) DO VALEUR = VALEUR + 3; VALEUR = VALEUR + 1; Ajoutent 3 chaque itration puis 1, une seule fois, quand elle est termine, car seule linstruction VALEUR = VALEUR + 3 est comprise dans litration

Condition avec IF THEN ELSE


Dusage beaucoup plus frquent, elle obit aux mmes principes dutilisation de BEGIN et END que la boucle WHILE. /* Calcul du plus grand de 2 nombres */ IF (Param1 > Param2) THEN Resultat = Param1 ; ELSE Resultat = Param2 ; Ce qui prcde pourra aussi scrire ainsi : /* Calcul du plus grand de 2 nombres */ IF (Param1 > Param2) THEN BEGIN Resultat = Param1 ; END ELSE BEGIN Resultat = Param2 ; END

Etienne Bar Dveloppeur et formateur indpendant http://www.sampathdev.com/ Page 16/27

et devra scrire obligatoirement ainsi sil y a plus de 2 instructions entre le if et le else ou aprs le else /* Calcul du plus grand de 2 nombres */ IF (Param1 > Param2) THEN BEGIN Resultat = Param1 ; Lequel = Premier ; END ELSE BEGIN Resultat = Param2 ; Lequel = Second ; END Il est bien sur tout fait possible dimbriquer plusieurs IF. IF (:PALIER1 IS NOT NULL) THEN BEGIN /* IL EXISTE UN PRIX SPCIFIQUE */ IF ((:PALIER3 IS NOT NULL) AND (QTETOTALE >= :PALIER3)) THEN BEGIN CLN_PRIX = PRIX3; END ELSE BEGIN IF ((:PALIER2 IS NOT NULL) AND (QTETOTALE >= :PALIER2)) THEN BEGIN CLN_PRIX = PRIX2; END ELSE BEGIN CLN_PRIX = PRIX1; END END PRIXTROUVE = -1; TYPETARIF = 1 ; END

Renvoi dinformations avec Suspend


Linstruction Suspend renvoie la valeur des variables contenues dans la clause Returns lappelant de la procdure stocke. Ainsi, la procdure stocke qui suit CREATE PROCEDURE AUCARRE RETURNS ( CARRE SMALLINT) AS DECLARE VARIABLE NBRE SMALLINT; /* Cette procdure stocke renvoie le carr des 10 premiers nombres */ BEGIN NBRE = 0 ; WHILE (NBRE < 10) DO BEGIN NBRE = NBRE + 1 ; CARRE = NBRE * NBRE ; SUSPEND ; END END Renvoie

Etienne Bar Dveloppeur et formateur indpendant http://www.sampathdev.com/ Page 17/27

alors que la procdure qui suit : CREATE PROCEDURE AUCARRE_2 RETURNS ( NBRE SMALLINT, CARRE SMALLINT) AS /* Cette procdure stocke renvoie le carr des 10 premiers nombres */ BEGIN NBRE = 0 ; WHILE (NBRE < 10) DO BEGIN NBRE = NBRE + 1 ; CARRE = NBRE * NBRE ; SUSPEND ; END END Renverra ce qui suit :

Cest donc ce qui est prsent dans lentte aprs linstruction RETURNS qui conditionne ce qui est renvoy lappelant.

Etienne Bar Dveloppeur et formateur indpendant http://www.sampathdev.com/ Page 18/27

2)

Utilisation de commandes SQL

Toutes les commandes SQL dInterbase (Select, Update, Insert, Delete) sont utilisables dans une procdure stocke. Les commandes du langage de dfinition de donnes (Create, Alter) ne sont pas utilisables. Il nest donc pas possible dagir sur la structure de la base par lintermdiaire dune procdure stocke.

Select
On diffrenciera les commandes qui ne renvoient quune ligne de donnes (Singleton Select) par opposition celle qui en renvoient plusieurs. La ou les lignes renvoyes par une commande SQL Select doivent tre stockes dans des variables pralablement dclares Ainsi, la commande SELECT COUNT(*) FROM EMPLOYEE

Sera utilise comme suit pour rcuprer la valeur dans la variable NBRE SELECT COUNT(*) FROM EMPLOYEE INTO :NBRE

Si le Select renvoie plusieurs lignes, on crira donc FOR SELECT first_name, last_name FROM EMPLOYEE INTO :Prenom, :Nom DO BEGIN /* Traitement dune ligne */ END ; Ainsi, la procdure stocke qui suit renvoie tous les projets affects un employ dont le code est pass en paramtre. CREATE PROCEDURE GET_EMP_PROJ ( EMP_NO SMALLINT) RETURNS ( PROJ_ID CHAR (5)) AS BEGIN FOR SELECT proj_id FROM employee_project WHERE emp_no = :emp_no INTO :proj_id DO SUSPEND; END

Etienne Bar Dveloppeur et formateur indpendant http://www.sampathdev.com/ Page 19/27

Procdure que pour ma part je prfre crire comme suit afin dviter une mauvaise surprise CREATE PROCEDURE GET_EMP_PROJ ( EMP_NO SMALLINT) RETURNS ( PROJ_ID CHAR (5)) AS BEGIN FOR SELECT proj_id FROM employee_project WHERE emp_no = :emp_no INTO :proj_id DO BEGIN SUSPEND; END END Notez que dans la ligne WHERE emp_no = :emp_no , le second :emp_no fait rfrence, ainsi que latteste les deux points au dbut de son nom, au paramtre dentre emp_no.

Update, Insert, Delete


Lutilisation des commandes Update, Insert, Delete ne prsente pas de diffrence par rapport aux commandes SQL classiques, si ce nest la possibilit dutiliser des variables. Nous allons crire une procdure stocke qui va mettre jour ou crer un client dans la table Customer selon que ce dernier existe ou non. Si le pays du client nexiste pas, on le cre avec Euro comme devise La recherche de lexistence du client se fait sur le libell du client (colonne Customer). Par simplification, on considre que deux clients ne peuvent pas avoir le mme libell. La procdure doit renvoyer le code du client cr ou mis jour et une rubrique indiquant si le pays a t cr. Les boolens ntant pas grs par interbase 6.0, on gre dans un entier avec vrai = -1 et faux = 0. On est ici en prsence dune utilisation judicieuse dune procdure stocke car un seul appel permet de crer ou de mettre jour des donnes dans deux tables distinctes, ce qui est bien sur impossible faire avec un seul ordre SQL.

Etienne Bar Dveloppeur et formateur indpendant http://www.sampathdev.com/ Page 20/27

CREATE PROCEDURE NOUVEAU_CLIENT ( NOMCLIENT VARCHAR (25), PRENOMNOMCONTACT VARCHAR (15), NOMCONTACT VARCHAR (20), PAYS VARCHAR (10)) RETURNS ( CODECLIENT INTEGER, PAYSCREE SMALLINT) AS /* Rdacteur : Etienne Bar Date de rdaction : 18/03/2004 Description : Cration d'un client ou mise jour du nom du contact si le client existe. Cration de la fiche pays si elle n'existe pas avec l'Euro comme monnaie par dfaut */ DECLARE VARIABLE LIBELLE_EXACT_PAYS VARCHAR(10) ;

BEGIN /* Corps de la procdure */ /* Le pays existe t'il ? /* Pour la recherche, on met tout en majuscules car InterBase est sensible la casse */ PAYS = UPPER(PAYS); SELECT COUNTRY FROM COUNTRY WHERE UPPER(COUNTRY) = UPPER(:PAYS) INTO LIBELLE_EXACT_PAYS ; /* On rcupre le libell du pays avec la casse correcte pour le stocker dans la table client de manire correcte */ IF (LIBELLE_EXACT_PAYS IS NULL) THEN BEGIN /* Cration du pays */ INSERT INTO COUNTRY(COUNTRY, CURRENCY) VALUES (:PAYS, 'EURO'); PAYSCREE = -1 ; LIBELLE_EXACT_PAYS = PAYS ; END ELSE BEGIN PAYSCREE = 0; END /* Recherche du client : on considre quon ne peut pas avoir 2 clients avec le mme libell. Dans le cas contraire, le code qui suit ne fonctionnerait pas */ SELECT CUST_NO FROM CUSTOMER WHERE UPPER(CUSTOMER) = UPPER(:NOMCLIENT) INTO :CODECLIENT ; /* Le client existe, on le met jour */ IF (CODECLIENT IS NOT NULL) THEN BEGIN UPDATE CUSTOMER SET CONTACT_FIRST = :PRENOMNOMCONTACT, Etienne Bar Dveloppeur et formateur indpendant http://www.sampathdev.com/ Page 21/27

CONTACT_LAST = :NOMCONTACT, COUNTRY =:LIBELLE_EXACT_PAYS WHERE (CUST_NO = :CODECLIENT) ; END ELSE BEGIN /* Le client est crer */ /* Ititialisation du code grace un gnrateur */ CODECLIENT = GEN_ID(CUST_NO_GEN,1) ; INSERT INTO CUSTOMER( CUST_NO, CUSTOMER, CONTACT_FIRST, CONTACT_LAST, COUNTRY) VALUES( :CODECLIENT, :NOMCLIENT, :PRENOMNOMCONTACT, :NOMCONTACT, :LIBELLE_EXACT_PAYS ) ; END /* Il ne faut surtout pas oublier le suspend final pour renvoyer le rsultat de la procdure */ SUSPEND ; END

Etienne Bar Dveloppeur et formateur indpendant http://www.sampathdev.com/ Page 22/27

Mise jour de donnes renvoyes par un select


Pour mettre jour des donnes, on utilisera bien sur une commande update, comme dans la procdure stocke qui suit et qui permet de remplacer les null par des espaces dans certains champs de la table customer. CREATE PROCEDURE REMPLACE_NULL_PAR_ESPACES AS DECLARE DECLARE DECLARE DECLARE BEGIN FOR /* Pour chaque ligne de la table customer */ SELECT CUST_NO, CONTACT_FIRST, CONTACT_LAST FROM CUSTOMER INTO :CODECLIENT, :PRENOMCONTACT, :NOMCONTACT DO BEGIN MAJ = 0; /* On ne fera la mise jour que si ncessaire */ IF (PRENOMCONTACT IS NULL) THEN BEGIN PRENOMCONTACT = ' '; MAJ = -1; END IF (NOMCONTACT IS NULL) THEN BEGIN NOMCONTACT = ' '; MAJ = -1; END IF (MAJ = -1) THEN BEGIN UPDATE CUSTOMER SET CONTACT_FIRST = :PRENOMCONTACT, CONTACT_LAST = :NOMCONTACT WHERE (CUST_NO = :CODECLIENT) ; END /* (MAJ = -1) */ END /* Pour chaque ligne de la table customer */ END VARIABLE VARIABLE VARIABLE VARIABLE CODECLIENT INTEGER; PRENOMCONTACT VARCHAR (15); NOMCONTACT VARCHAR (20); MAJ SMALLINT;

Etienne Bar Dveloppeur et formateur indpendant http://www.sampathdev.com/ Page 23/27

Excution de procdures stockes

3)

Terminer une procdure stocke avant la dernire instruction

Fin dexcution avec EXIT


Linstruction exit interrompt la procdure en cours.

Gestion derreurs avec la commande Exception


Il est possible de lever une exception dans une procdure stocke. Cette exception doit avoir t pralablement cre laide de linstruction CREATE EXCEPTION. Comme il sagit dune instruction qui a un impact sur la structure de la base, une exception ne peut pas tre cre dans une procdure stocke. On la crera donc au pralable. CREATE EXCEPTION REAFFECTE_VENTES 'Cet employ a des ventes enregistres dans la base de donnes' Et on lutilisera comme suit dans une procdure stocke (rendons Csar ce qui est Csar : Lexemple qui suit nest que la traduction au niveau des commentaires- de la procdure DELETE_EMPLOYEE place dans les exemples de la base)

Etienne Bar Dveloppeur et formateur indpendant http://www.sampathdev.com/ Page 24/27

CREATE PROCEDURE EFFACE_EMPLOYEE ( EMP_NUM INTEGER) AS DECLARE VARIABLE any_sales INTEGER; BEGIN any_sales = 0; /* Si des ventes sont affectes cet employ, on ne peut l'effacer avant d'avoir affect les ventes un autre employ */ SELECT COUNT(PO_NUMBER) FROM sales WHERE sales_rep = :emp_num INTO :any_sales; IF (any_sales > 0) THEN BEGIN EXCEPTION REAFFECTE_VENTES; END /* Si l'employ est un manager, modifier le dpartement */ UPDATE department SET mngr_no = NULL WHERE mngr_no = :emp_num; /* Si l'employ est le chef d'un projet, mettre jour le projet */ UPDATE PROJECT SET team_leader = NULL WHERE team_leader = :emp_num; /* Supprimer l'employ des projets auxquels il participe */ DELETE FROM employee_projecT WHERE emp_no = :emp_nuM; /* Supprimer l'historique de l'employ */ DELETE FROM salary_history WHERE emp_no = :emp_num; /* Supprimer l'employ de la table Employee */ DELETE FROM employee WHERE emp_no = :emp_num; END

Etienne Bar Dveloppeur et formateur indpendant http://www.sampathdev.com/ Page 25/27

Et si on excute cette procdure avec un employ ayant des ventes, on reoit en rponse :

ce qui est bien leffet escompt.

Documentation officielle sur les procdures stockes


Dans la documentation officielle Interbase, vous trouverez dautres informations (en anglais) sur les procdures stockes dans les ouvrages suivants : Nom de louvrage Data Definition Guide Nom et emplacement du fichier correspondant au livre \InterBase\Doc\DataDef\DataDef.pdf Chapitre Working with stored procdures Working with stored procdures Pages Contenu 135174 211218 Dclaration et critures des procdures stockes Utilisation et gestion des procdures stockes avec les produits Borland (Delphi, C++ Builder, JBuilder) Utilisation des procdures stockes en C/C++ Manuel de rfrence

DeveloperGuide \InterBase\Doc\DevGuide\ DevGuide.pdf

Embedded SQL Guide Language reference

\InterBase\Doc\ EmbedSQL \EmbedSQL.pdf \InterBase\Doc\LangRef\ LangRef.pdf

Working with stored procdures Procdures and Triggers

225232 161182

En conclusion
Ce document nest quune introduction aux procdures stockes, il reste un certain nombre de choses voir. Je nai pas par exemple voqu la gestion des erreurs. Il va de soi que lutilisation dune procdure stocke implique davoir les privilges adquats pour lutilisateur qui la lance sur les tables quelle manipule. Enfin, il est mon avis illusoire de vouloir crire des procdure stocke consquentes sans un environnement de dveloppement digne de ce nom. Jutilise pour ma part EMS IB Manager et jen suis assez satisfait. Il en existe dautres, je vous laisse faire votre choix. Pour amliorer votre connaissance des procdures stockes, je vous conseille de regarder celles existant dans la base employe et de bien les comprendre.

Etienne Bar Dveloppeur et formateur indpendant http://www.sampathdev.com/ Page 26/27

Annexe 1 : Schma de la base employee

(Rtro conception de la base de donnes effectue avec Case Studio www.CaseStudio.com) NN => Non Null PK => Cl primaire FK => Cl trangre

Etienne Bar Dveloppeur et formateur indpendant http://www.sampathdev.com/ Page 27/27

You might also like