Sie sind auf Seite 1von 29

Forums Tutoriels Magazine FAQs Blogs Projets Chat Newsletter tudes Emploi Club Contacts

Accueil ALM Java .NET Dv. Web EDI Langages SGBD Office Solutions d'entreprise Applications Mobiles Systmes
SGBD 4D Access DB2 Firebird
FAQs SGBD

InterBase

MySQL

NoSQL

Oracle

PostgreSQL

SQL-Server

Sybase

Forums SGBD

Tutoriels SGBD

SQL

Outils SGBD

Livres SGBD et SQL

Petit guide de Transact SQL (v2000)


Date de publication : 16/04/2004 Par SQLPro niveau : intermdiaire Transact SQL, est une extension du dialecte SQL de SQL Server et constitue un langage procdural pour coder les procdures stockes et les triggers du SGBDR de Le but de cet article est de prsenter rapidement les concepts ncessaires une bonne introduction ce langage et ses possibilits. 1. Positionnement du langage 1.1. Historique 1.2. Utilisation 1.3. Conclusion 2. Syntaxe 2.1. Identifiant 2.2. Variables 2.3. Structures basiques 2.4. Variable de retour 2.5. Variables "systme" 2.6. Flags 2.7. Batch et GO 2.8. Quelques fonctions de base 2.9. Commentaires 3. UDF : fonction utilisateur 3.1. Fonction renvoyant une valeur 3.2. Fonction renvoyant une table 4. Procdures stockes 4.1. Entte de procdure 4.2. Paramtres, variables de retour et ensemble de donnes 4.3. Gestion des erreurs 4.4. Procdures stockes prdfinies 4.5. Verrouillage 4.6. Gestion de transactions 4.7. Les curseurs 5. Les triggers 5.1. Mise en place d'un trigger 5.2. Syntaxe d'un trigger MS SQL Server 2000 5.3. Elments du langage spcifique aux triggers 5.3.1. Pseudo tables INSERTED et DELETED 5.3.2. Fonctions UPDATE et COLUMNS_UPDATED 5.3.3. Annulation des effets d'un trigger 5.4. Exemples de triggers 6. Cryptage du code, liaison au schema et recompilation 7. ANNEXE BIBLIOGRAPHIQUE

1. Positionnement du langage

Transact SQL est un langage procdural (par opposition SQL qui est un langage dclaratif) qui permet de programmer des algorithmes de traitement des donnes a Sybase Adaptive Server et Microsoft SQL Server.

1.1. Historique
Il a t cr par Sybase INC. la fin des annes 80 pour rpondre aux besoins d'extension de la programmation des bases de donnes pour son SGBDR. Ce langage est donc commun aux deux produits (MS SQL Server et Sybase Adaptive) avec des diffrences mineures dans les implmentations. Il sert programmer des procdures stockes et des triggeurs (dclencheurs).

Transact SQL n'a aucun aspect normatif contrairement SQL. C'est bien un "produit" au sein commercial du terme. En revanche depuis SQL 2 et plus fortement main 3, la norme SQL a prvu les lments de langage procdural normatif propre au langage SQL. Mais il y a une trs grande diffrence entre la norme du SQL procdural

D'autres SGBDR utilisent d'autres langages procduraux pour l'implmentation de procdures stockes et de triggers. C'est le cas par exemple du PL/SQL (Prog d'Oracle. Il existe encore peu de SGBDR dont le langage procdural est cal sur la norme. Mais on peut citer OCELOT (SQL 3), PostGreSQL (SQL 2). Par rapport la concurrence voici une notation approximative (sur 5) des diffrents langage procduraux : SGBDR Langage Respect norme Richesse

sqlpro.developpez.com/cours/sqlserver/transactsql/

1/29

Oracle 8 MS SQL Server v7 PostGreSQL OCELOT

PL/SQL Transact SQL SQL 2 SQL3

3/5 2/5 4/5 5/5 3/5

5/5 3/5 4/5 4/5 3/5

InterBase ISQL Il s'agit bien entendu d'une notation toute personnelle parfaitement sujette caution !

1.2. Utilisation
Transact SQL doit tre utilis :

dans les procdures stockes, pour les calculs portant sur des donnes internes la base, sans considration de gestion d'IHM. Exemple pr calculs d'agrgats d'accs... dans les triggers, pour dfinir et tendre des rgles portant sur le respect de l'intgrit des donnes. Exemple formatage de donnes, liens d'hritage exclusif e

En revanche il faut tenter de ne pas l'utiliser pour le calculs de rgles mtier, l'idal tant de dporter cela dans des objets mtiers. Enfin l'usage de trigger pour de l proscrire.

1.3. Conclusion

Nous retiendrons que ce qui compte dans l'tude de ce langage, c'est plus de comprendre ses grands concepts et son esprit afin de pouvoir le transposer sur d'au que d'apprendre par cur telle ou telle instruction, d'autant que la documentation sur ce langage est assez fournie. ATTENTION : nous tudirons ici la version Microsoft du langage Transact SQL

2. Syntaxe
2.1. Identifiant
Voici les rgles de codage des identifiants (nom des objets) Les identifiants SQL : ne peuvent dpasser 128 caractres. Ils doivent commencer par une lettre ou un "underscore". Les caractres spciaux et le blanc ne sont pas admis. On se contentera d'utiliser les 37 caractres de base : ['A'..'Z', '0'..'9', '_'] La casse n'a pas d'importance. Le symbole @ commence le nom de toute variable. Le symbole ddoubl @@ commence le nom des variables globales du SGBDR. Le symbole # commence le nom de toute table temporaire (utilisateur) Exemple :
S E L E C TC U R R E N T _ T I M E S T A M Pa sD a t e T i m e I N T O# t e m p T S E L E C T* F R O M# t e m p T

Le symbole ddoubl ## commence le nom de toute table temporaire globale. Consquence : la libration des tables temporaires est conscutif la libration des utilisteurs. Nota : SQL Server utilise un base particulire "tempDB" pour stocker la dfinition des objets temporaires. Attention : pour des raisons de performances il est fortement dconseill d'utiliser le SELECT INTO qui n'est d'ailleurs pas normalis. Un identifiant est dit "qualifi" s'il fait l'objet d'une notation pointe dfinissant le serveur, la base cible et l'utilisateur :
s e r v e u r . b a s e _ c i b l e . u t i l i s a t e u r . o b j e t

Exemple :
S E L E C T*F R O MM o n S e r v e u r . M a B a s e . M o n U s e r . M a T a b l e

Attention : ceci suppose que les serveurs soient connus les uns des autres (procdure de "linkage") On peut ignorer le serveur, comme l'utilisateur, dans ce cas c'est l'utilisateur courant qui est pris en compte :
b a s e _ c i b l e . . o b j e t

et au sein de la base :
o b j e t

Un identifiant ne doit pas tre un mot clef de SQL, ni un mot clef de SQL Server ni mme un mot rserv. Dans le cas contraire il faut utiliser les guillemets comme d La notion de constante n'existe pas dans Transact SQL.

sqlpro.developpez.com/cours/sqlserver/transactsql/

2/29

2.2. Variables
Les types disponibles sont ceux de SQL :
b i t ,i n t ,s m a l l i n t ,t i n y i n t ,d e c i m a l ,n u m e r i c ,m o n e y ,s m a l l m o n e y ,f l o a t ,r e a l ,d a t e t i m e ,s m a l l d a t e t i m e ,t i m e s t a m p , u n i q u e i d e n t i f i e r ,c h a r ,v a r c h a r ,t e x t ,n c h a r ,n v a r c h a r ,n t e x t ,b i n a r y ,v a r b i n a r y ,i m a g e .

Auxquels il faut ajouter le type :


c u r s o r

que nous verrons plus en dtail. Les valeurs de types chanes doivent tre dlimites par des apostrophes. Une variable est dclare tout endroit du code par l'instruction DECLARE : Exemple :
D E C L A R E@ m a C h a i n ec h a r ( 3 2 )

Une variable est assigne par l'instruction SET :


S E T@ m a C h a i n e=' t o t o '

Avant toute assignation, une variable dclare est marque NULL. Remarques :

il n'existe pas de type "tableau" dans le langage Transact SQL. Cependant, une table temporaire suffit un tel usage. l'ordre SQL SELECT peut aussi servir assigner une ou plusieurs variable, mais dans ce dernier cas il faut veiller ce que la rponse la requte ne produise qu Exemple :
S E L E C T@ N o m T a b l e=' T A B L E S ' ,@ N o m b r e L i g n e=c o u n t ( * ) F R O MI N F O R M A T I O N _ S C H E M A . T A B L E S

Attention : dans le cas d'une requte renvoyant plusieurs lignes, seule la valeur de la dernire ligne sera rcupr dans la variable. ASTUCE : si vous dsirez concatner toutes les valeurs d'une colonne dans une seule variable, vous pouvez utiliser la construction suivante :
D E C L A R E@ C o l o n n ev a r c h a r ( 8 0 0 0 ) S E T@ C o l o n n e=' ' S E L E C T@ C o l o n n e=@ C o l o n n e+ C O A L E S C E ( T A B L E _ N A M E+' ,' ,' ' ) F R O MI N F O R M A T I O N _ S C H E M A . T A B L E S

NOTA : la notion de constante n'existe pas.

2.3. Structures basiques


La structure :
B E G I N . . . E N D

permet de dfinir des blocs d'instructions. Les branchements possibles sont les suivants :
I F[ N O T ]c o n d i t i o ni n s t r u c t i o n[ E L S Ei n s t r u c t i o n ] I F[ N O T ]E X I S T S ( r e q u t es e l e c t )i n s t r u c t i o n[ E L S Ei n s t r u c t i o n ] W H I L Ec o n d i t i o ni n s t r u c t i o n G O T Oe t i q u e t t e W A I T F O R[ D E L A Y|T I M E ]t e m p s

Les instructions :
B R E A K C O N T I N U E

permettent respectivement d'interrompre ou de continuer autoritairement une boucle. Remarques : il n'y a pas de THEN dans le IF du Transact SQL, ni de DO dans le WHILE une seule instruction est permise pour les structure IF et WHILE, sauf mettre en place un bloc d'instructions l'aide d'une structure BEGIN / END un branchement sur tiquette se prcise avec en suffixant l'identifiant de l'tiquette avec un caractre deux-points ':' Exemple : Il s'agit de donner la liste de tous les nombres premiers entre 1 et 5000. Premire version en code procdural :
/ *r e c h e r c h ed et o u sl e sn o m b r e sp r e m i e r sd e15 0 0 0* / / *v e r s i o np r o c d u r a l e( i t r a t i o n s ) * / -c r a t i o nd ' u n et a b l ep r o v i s o i r ep o u rs t o c k a g ed e sd o n n e s c r e a t et a b l e# n( ni n t )

sqlpro.developpez.com/cours/sqlserver/transactsql/

3/29

d e c l a r e@ ni n t e g e r ,@ ii n t e g e r ,@ p r e m i e rb i t s e t@ n=1 s e tn o c o u n to n -u nn o m b r ep r e m i e rn ' e s td i v i s i b l eq u ep a r1e tl u im m e w h i l e@ n<5 0 0 0 B E G I N -o np r s u p p o s eq u ' i le s tp r e m i e r s e t@ p r e m i e r=1 s e t@ i=2 w h i l e@ i<@ n B E G I N -a u t r e m e n td i t ,t o u td i v i s e u rs i t u e n t r e2e tl u im m em o i n su n -f a i tq u ec en o m b r en ' e s tp a sp r e m i e r i f( @ n/@ i )*@ i=@ n S E T@ p r e m i e r=0 S E T@ i=@ i+1 E N D i f@ p r e m i e r=1 i n s e r ti n t o# nV A L U E S( @ n ) S E T@ n=@ n+1 E N D S E L E C T*F R O M# n

Par ce code procdural, nous avons utilis la formulation suivante : "n est premier si aucun nombre de 2 n-1 ne le divise".

Une autre faon de faire est de travailler en logique ensembliste. Si nous disposons d'une table des entiers, il est alors facile de comprendre que les nombres prem nombres, moins ceux qui ne sont pas premiers... Il s'agit ni plus ni moins que de raliser une diffrence ensembliste.
/ *r e c h e r c h ed et o u sl e sn o m b r e sp r e m i e r sd e15 0 0 0* / / *v e r s i o ne n s e m b l i s t e( r e q u t e s ) * / D E C L A R E@ m a xi n t S E T@ m a x=5 0 0 0 -c e te x e m p l eu t i l i s el al o g i q u ee n s e m b l i s t ep o u rc a l c u l e rt o u sl e sn o m b r e se n t i e r s S E TN O C O U N TO N -t a b l et e m p o r a i r ed es t o c k a g ed e se n t i e r sd e15 0 0 0 C R E A T ET A B L E# n( ni n t ) -b o u c l ed ' i n s e r t i o nd e05 0 0 0 D E C L A R E@ ii n t S E T@ i=0 W H I L E@ i<@ m a x B E G I N I N S E R TI N T O# nV A L U E S( @ i ) S E T@ i=@ i+1 E N D -o np r e n dt o u sl e se n t i e r sd el at a b l enm o i n sl e se n t i e r sd el at a b l enp o u r -l e s q u e l sl er e s t ed el ad i v i s i o ne n t i r e( m o d u l o )p a ru ne n t i e rm o i n d r ed o n n e0 -N O T Al ' o p r a t i o nM O D U L Os en o t e%d a n sT r a n s a c tS Q L S E L E C Td i s t i n c tn F R O M# n W H E R Enn o ti n( S E L E C Td i s t i n c tn 1 . n F R O M # nn 1 C R O S SJ O I N# nn 2 W H E R En 1 . n%n 2 . n=0 A N Dn 2 . nB E T W E E N2A N Dn 1 . n-1 ) O R D E RB Yn

Notez la diffrence de vistesse d'excution entre les deux manires de faire... Enfin, on peut encore optimiser l'une et l'autre des procdure en limitant le diviseur au maximum CAST(SQRT(CAST(n2.n AS FLOAT)) AS INTEGER) + 1, car diviseurs d'un nombre ne peut dpasser sa racine carre.

2.4. Variable de retour

Toute procdure stocke renvoie une variable de type entier pour signaler son tat. Si cette variable vaut 0, la procdure s'est droule sans anomalie. Tout autre problme. Les valeurs de 0 -99 sont rserves et celles de 0 -14 sont prdfinies. Par exemple la valeur -5 signifie erreur de syntaxe. On peut assigner une valeur de retour de procdure l'aide de l'instruction RETURN :
R E T U R N1 4 4 5

2.5. Variables "systme"


SQL Server dfini un grand nombre de "variables systme" c'est dire des variables dfinies par le moteur. En voici quelques unes : Variable @@connections @@datefirts @@error @@fetch_status @@identity @@max_connections @@procid @@rowcount @@servername @@spid @@trancount nombre de connexions actives premier jour d'une semaine (1:lundi 7:dimanche) code de la dernire erreur rencontre (0 si aucune) tat d'un curseur lors de la lecture (0 si lecture proprement excute) nombre maximums d'utilisateurs concurrents identifiant de la procdure stocke en cours nombre de lignes concernes par le dernier ordre SQL nom du serveur SGBDR courant identifiant du processus en cours nombre de transaction en cours Description

dernire valeur insre dans une colonne auto incrmente pour l'utilisate

2.6. Flags
sqlpro.developpez.com/cours/sqlserver/transactsql/ 4/29

Pour manipuler les effets de certaines variables, comme pour paramtrer la base de donnes, il est ncessaire de recourir des "flags".

SET NOCOUNT ON / OFF empche/oblige l'envoi au client de messages pour chaque instruction d'une procdure stocke affichant la ligne nn rows affected la fin d'une instruction UPDATE, DELETE). Remarque : il est recommand de dsactiver le comptage dans les procdures stockes afin d'viter l'envoi intempestif de lignes non lues qui gnre du trafic rse temps d'excution. SET ANSI_DEFAULTS ON / OFF Conformation d'une partie de SQL Server la norme SQL 2 SET DATEFORMAT {format de date} Fixation du format de date par dfaut SET IDENTITY_INSERT nomTable ON / OFF Active, dsactive l'insertion automatique de colonne auto incrmentes (identity) dans la table spcifie. Exemple : insertion de lignes dont la clef est spcifie dans une table donnes pourvue d'un auto incrment :
C R E A T ET A B L ET _ C L I E N T ( C L I _ I DI N T E G E RI D E N T I T YN O TN U L LP R I M A R YK E Y , C L I _ N O MV A R C H A R ( 3 2 ) ) S E TI D E N T I T Y _ I N S E R TT _ C L I E N TO N I N S E R TI N T OT _ C L I E N T( C L I _ I D ,C L I _ N O M )V A L U E S( 3 2 5 ,' D U P O N T ' ) I N S E R TI N T OT _ C L I E N T( C L I _ I D ,C L I _ N O M )V A L U E S( 9 8 7 ,' M A R T I N ' ) S E TI D E N T I T Y _ I N S E R TT _ C L I E N TO F F I N S E R TI N T OT _ C L I E N T( C L I _ I D ,C L I _ N O M )V A L U E S( 5 1 2 ,' L E V Y ' ) = >S e r v e u r :M s g5 4 4 ,N i v e a u1 6 , t a t1 ,L i g n e1 I m p o s s i b l ed ' i n s r e ru n ev a l e u re x p l i c i t ed a n sl ac o l o n n ei d e n t i t d el at a b l e' T _ C L I E N T 'q u a n dI D E N T I T Y _ I N S E R T e s td f i n iO F F .

2.7. Batch et GO

Un batch est un ensemble d'ordres SQL ou Transact SQL pass en un lot. Il peut tre excut en lanant un fichier vers le moteur SQL ou encore en l'excutant d requtes. la plupart du temps un batch est utilis pour crer les objets d'une base et lancer au coup par coup certaines procdures lourdes (administration notamment).

Le mot clef GO permet de forcer l'excution de diffrents ordres SQL d'un traitement par lot. Hors d'un contexte de transaction, le serveur peut choisir dans les dif luis ont proposs simultanment d'excuter telle ou telle demande dans l'ordre que bon lui semble. La prsence du mot clef GO dans un fichier d'ordre SQL pass au serveur permet de lui demander l'excution immdiate de cet ordre ou de l'ensemble d'ordr l'instruction GO doit tre spcifi pour chaque ordre atomique ou bien pour chaque ensemble cohrents. En fait le mot clef GO agit comme si chaque ordre tait lanc travers un fichier diffrent. Enfin, un batch est excut en tout ou rien. Ainsi, en cas d'erreur de syntaxe par exemple, mme sur le dernier ordre du lot, aucun des ordres n'est excut. Attention : Certains ordres ne peuvent tre passs simultanment dans le mme lot. Par exemple la suppression d'un objet (DROP) et sa re cration immdiatement aprs, source de conflits. Le mot clef GO n'est valable que pour une excution par lot (batch). Il n'est donc pas reconnu au sein d'une procdure stocke ni dans le code d'un trigger

2.8. Quelques fonctions de base

USE est une instruction permettant de prciser le nom de la base de donnes cible. En effet il arrive que l'on soit oblig de travailler depuis une base pour en traite le cas notamment lorsque l'on veut crer une base de donnes et y travailler sur le champ. La seule base en standard dans MS SQL Server est la base "master " qui sert de matrice toutes les bases cres. Elle contient les procdures inhrentes au serveu inhrentes aux bases nouvellement cres, ainsi que les mta donnes spcifiques de la nouvelle base (tables dont le nom commence par "syS..."). Exemple : cration d'une base de donnes depuis la base MASTER et cration d'une table dans cette nouvelle base :
C R E A T ED A T A B A S EN E W _ M A B A S E O N (N A M E=' N E W _ M A B A S E _ D B ' , F I L E N A M E=' C : \ M a B a s e . D A T A ' , S I Z E=1 0 0 , M A X S I Z E=5 0 0 , F I L E G R O W T H=5 0) L O GO N (N A M E=' N E W _ M A B A S E _ L O G ' , F I L E N A M E=' C : \ M a B a s e . L O G ' , S I Z E=5 , M A X S I Z E=2 5 , F I L E G R O W T H=5) G O U S EN E W _ M A B A S E G O C R E A T ET A B L ET _ C L I E N T ( C L I _ I D I N T E G E RI D E N T I T YN O TN U L LP R I M A R YK E Y , C L I _ N O MV A R C H A R ( 3 2 ) ) G O

PRINT est une instruction permettant de gnrer une ligne en sortie de procdure. Elle doit tre rserve plus la mise au point des procdures stockes que pour exploitation.

EXEC est une instruction permettant de lancer une requte ou une procdure stocke au sein d'une procdure ou un trigger. La plupart du temps il n'est pas n l'instruction EXEC, si l'intgralit de la commande SQL ou de la procdure lancer est connu. Mais lorsqu'il s'agit par exemple d'un ordre SQL contenant de nombreux il est ncessaire de le dfinir dynamiquement.

sqlpro.developpez.com/cours/sqlserver/transactsql/

5/29

Exemple : voici une procdure cherchant dans toutes les colonnes d'une table l'occurrence d'un mot :
D E C L A R E @ T a b l e N a m eV a r c h a r ( 1 2 8 ) , @ S e a r c h W o r dV a r c h a r ( 3 2 ) D e c l a r e@ C o l u m n L i s tv a r c h a r ( 1 0 0 0 ) D e c l a r e@ S Q Lv a r c h a r ( 1 2 0 0 )

-n o md el at a b l ep a s s e na r g u m e n t -m o tr e c h e r c h -l i s t ed e sn o m sd ec o l o n n e sd a n s -l e s q u e l sl ar e c h e r c h ev as ' e f f e c t u e r -r e q u t ed er e c h e r c h e

-o b t e n t i o nd el al i s t ed e sc o l o n n e sp o u rl ar e q u t ed er e c h e r c h e S E L E C T@ C o l u m n L i s t=C O A L E S C E ( @ C o l u m n L i s t+'+C O A L E S C E ( ' ,' C O A L E S C E ( ' )+c o l u m n _ n a m e+ ' ,' ' ' ' ) ' F R O M I N F O R M A T I O N _ S C H E M A . C O L U M N S W H E R E T A B L E _ N A M E=@ T a b l e N a m e A N D D A T A _ T Y P EL I K E' % c h a r % ' P R I N T' I N F O-@ C o l u m n L i s tv a l u ei s:'+@ C o l u m n L i s t-j u s t ep o u rv o i r! -a s s e m b l a g ed ut e x t ed el ar e q u t ed er e c h e r c h e S e t@ S Q L= ' S E L E C T*F R O M' +@ T a b l e N a m e +'W H E R E' +@ C o l u m n L i s t +'L I K E' ' % ' +@ S e a r c h W o r d+ ' % ' ' ' P R I N T' I N F O-@ S Q Lv a l u ei s:'+@ S Q L -e x c u t i o nd el ar e q u t ed er e c h e r c h e E x e c( @ S Q L ) -j u s t ep o u rv o i r!

2.9. Commentaires
Comme dans le cadre du langage SQL de base, pour placer des commentaries il suffit d'utiliser les marqueurs suivants : Dbut -/* */ Fin Commentaire pour une ligne de commentaire pour un bloc de ligne ou de caractres

3. UDF : fonction utilisateur

Une UDF, autrement dit User Define Function ou Function Dfinie par l'Utilisateur est une fonction que le concepteur de la base crit pour des besoins de traite requtes et du code des procdures stockes ou des triggers. Elle fait donc partie intgrante de la base ou elle est considre comme un objet de la base au mme une vue, un utilisateur ou une procdure stocke. Il existe deux grands types de fonctions : celles renvoyant une valeur et celles renviyant un jeu de donnes (table).

3.1. Fonction renvoyant une valeur


La syntaxe est assez simple :
C R E A T E F U N C T I O N[u t i l i s a t e u r .]n o m _ f o n c t i o n ([{@ p a r a m e t r e 1 [ A S ]t y p e[=v a l e u r _ d f a u t]}[,@ p a r a m e t r e 2. . .]]) R E T U R N St y p e _ r s u l t a n t [A S] B E G I N c o d e R E T U R Nv a l e u r _ r s u l t a n t e E N D

Exemple, calcul de la date de pque pour une anne donne :


C R E A T EF U N C T I O NF N _ P A Q U E( @ A NI N T ) R E T U R N SD A T E T I M E A S B E G I N -A l g o r i t h m ec o n up a rC l a u sT n d e r i n g. -C o p y r i g h t( C )1 9 9 8b yC l a u sT o n d e r i n g . -E m a i l :c l a u s @ t o n d e r i n g . d k . I F@ A NI SN U L L R E T U R NN U L L D E C L A R E@ GI N T D E C L A R E@ II N T D E C L A R E@ JI N T D E C L A R E@ CI N T D E C L A R E@ HI N T D E C L A R E@ LI N T D E C L A R E@ J o u r P a q u eI N T D E C L A R E@ M o i s P a q u eI N T D E C L A R E@ D i m P a q u eD A T E T I M E

sqlpro.developpez.com/cours/sqlserver/transactsql/

6/29

S E T@ G=@ A N%1 9 S E T@ C=@ A N/1 0 0 S E T@ H=( @ C-@ C/4-( 8*@ C+1 3 )/2 5+1 9*@ G+1 5 )%3 0 S E T@ I=@ H-( @ H/2 8 )*( 1-( @ H/2 8 )*( 2 9/( @ H+1 ) )*( ( 2 1-@ G )/1 1 ) ) S E T@ J=( @ A N+@ A N/4+@ I+2-@ C+@ C/4 )%7 S E T@ L=@ I-@ J S E T@ M o i s P a q u e=3+( @ L+4 0 )/4 4 S E T@ J o u r P a q u e=@ L+2 8-3 1*( @ M o i s P a q u e/4 ) S E T@ D i m P a q u e=C A S T ( C A S T ( @ A NA SV A R C H A R ( 4 ) )+ C A S E W H E N@ M o i s P a q u e<1 0T H E N' 0 '+C A S T ( @ M o i s P a q u eA SC H A R ( 1 ) ) E L S E C A S T ( @ M o i s P a q u eA SC H A R ( 2 ) ) E N D+ C A S E W H E N@ J o u r P a q u e<1 0T H E N' 0 '+C A S T ( @ J o u r P a q u eA SC H A R ( 1 ) ) E L S E C A S T ( @ J o u r P a q u eA SC H A R ( 2 ) ) E N D A SD A T E T I M E ) R E T U R N@ D i m P a q u e E N D

On utilise une telle fonction au sein d'une requte, comme une fonction SQL de base, ceci prs que, pour une raion obscure, il faut la faire prcder du nom du pro Exemple :

S E L E C Td b o . F N _ P A Q U E( 2 0 0 4 )A SP A Q U E _ 2 0 0 4

P A Q U E _ 2 0 0 4 2 0 0 4 0 4 1 10 0 : 0 0 : 0 0 . 0 0 0

3.2. Fonction renvoyant une table


Il existe deux manires de procder : soit par requte directe (table en ligne), soit par construction et alimentation d'une table (table multi instruction). La premire syntaxe (table est ligne) est trs simple. Voici un exemple, qui construit et renvoi une table des jours de semaine :

C R E A T EF U N C T I O NF N _ J O U R _ S E M A I N E( ) R E T U R N ST A B L E A S R E T U R N( S E L E C T1A SN ,' L u n d i 'A SJ O U R U N I O N S E L E C T2A SN ,' M a r d i 'A SJ O U R U N I O N S E L E C T3A SN ,' M e r c r e d i 'A SJ O U R U N I O N S E L E C T4A SN ,' J e u d i 'A SJ O U R U N I O N S E L E C T5A SN ,' V e n d r e d i 'A SJ O U R U N I O N S E L E C T2A SN ,' S a m e d i 'A SJ O U R U N I O N S E L E C T2A SN ,' D i m a n c h e 'A SJ O U R ) S E L E C T* F R O Md b o . F N _ J O U R _ S E M A I N E( ) N J O U R -1 L u n d i 2 D i m a n c h e 2 M a r d i 2 S a m e d i 3 M e r c r e d i 4 J e u d i 5 V e n d r e d i

La seconde syntaxe demande un peu plus de travail, car elle se base sur une variable "table". En voici la syntaxe :
C R E A T E F U N C T I O N[u t i l i s a t e u r .]n o m _ f o n c t i o n ([{@ p a r a m e t r e 1 [ A S ]t y p e[=v a l e u r _ d f a u t]}[,@ p a r a m e t r e 2. . .]]) R E T U R N St y p e _ r s u l t a n tT A B L E<d e f i n i t i o n _ d e _ t a b l e> [A S] B E G I N c o d e R E T U R N E N D

Voici un exemple, qui construit une table d'entier limit MaxInt et comprenant ou non le zro (entiers naturels) :

C R E A T EF U N C T I O NF N _ E N T I E R S( @ M A X I N Ti n t e g e r ,@ N A T U R E Lb i t=0 ) R E T U R N S@ i n t e g e r sT A B L E ( Ni n tP R I M A R YK E YN O TN U L L ) A S B E G I N D E C L A R E@ NI N T D E C L A R E@ TT A B L E( Ni n t )

sqlpro.developpez.com/cours/sqlserver/transactsql/

7/29

S E T@ N=0 -i n s e r t i o nd e s1 0p r e m i e r sc h i f f r e sd e09 W H I L E@ N<1 0 B E G I N I N S E R TI N T O@ TV A L U E S( @ N ) S E T@ N=@ N+1 E N D S E T@ N=@ N1 -s i@ Ne s ts u p r i e u r9 ,a l o r ss u p p r i m e rl e sv a l e u r se nt r o p I F@ N>@ M A X I N T D E L E T EF R O M@ TW H E R EN>@ M A X I N T E L S E I N S E R TI N T O@ T S E L E C TD I S T I N C T1*T 1 . N+1 0*T 2 . N+ +1 0 0*T 3 . N+1 0 0 0 *T 4 . N F R O M @ TA ST 1 C R O S SJ O I N@ TA ST 2 C R O S SJ O I N@ TA ST 3 C R O S SJ O I N@ TA ST 4 W H E R E 1*T 1 . N+1 0*T 2 . N+ +1 0 0*T 3 . N+1 0 0 0 *T 4 . NB E T W E E N1 0A N D@ M A X I N T

-s ' i ls ' a g i td ' e n t i e r sn a t u r e l s ,s u p p r i m e rl ez r o I F@ N A T U R E L=1 D E L E T EF R O M@ TW H E R EN=0 -i n s e r t i o nd a n sl av a r i a b l ed er e t o u r I N S E R TI N T O@ i n t e g e r s S E L E C TD I S T I N C TNF R O M@ T R E T U R N E N D S E L E C T* F R O M d b o . F N _ E N T I E R S( 1 3 ,1 ) N 1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3

NOTA : SQL Server interdit l'utilisation de fonctions non dterministe au sein des fonctions utilisateur. Par exemple, la fonction CURRENT_TIMESTAMP qui renv courante ne peut tre utilise dans le cadre de l'criture d'une UDF. Il y a cependant moyen de contourner ce problme en utilisant par exemple une vue...

C R E A T EV I E WV _ D A T E H E U R E _ C O U R A N T E A S S E L E C TC U R R E N T _ T I M E S T A M PA SD H C C R E A T EF U N C T I O NF N _ D E L T A _ M O N T H( @ M a D a t eD A T E T I M E ) R E T U R N SI N T A S B E G I N D E C L A R E@ NI N T S E L E C T@ N=D A T E D I F F ( M O N T H ,@ M a D a t e ,D H C ) F R O M V _ D A T E H E U R E _ C O U R A N T E R E T U R N@ N E N D S E L E C Td b o . F N _ D E L T A _ M O N T H ( ' 2 0 0 2 0 1 0 1 ' )

4. Procdures stockes
Le but d'une procdure stocke est triple : tendre les possibilits des requtes, par exemple lorsqu'un seul ordre INSERT ou SELECT ne suffit plus faciliter la gestion de transactions permettre une excution plus rapide et plus optimise de calculs complexes ne portant que sur des donnes de la base Dans ce dernier cas la mthode traditionnelle ncessitait de nombreux aller et retour entre le client et le serveur et congestionnait le rseau. Une procdure stocke est accessible par l'interface de l'Entreprise Manager. Elle peut aussi tre cre par l'analyseur de requte.

sqlpro.developpez.com/cours/sqlserver/transactsql/

8/29

En crant une nouvelle procdure stocke on se trouve devant une fentre de dfinition de code :

ATTENTION : Les procdures stockes (v7) sont limites : 128 Mo de code 1024 paramtres en argument (y compris curseurs)

4.1. Entte de procdure


Elle commence toujours pas les mots clef CREATE PROCEDURE suivi du nom que l'on veut donner la procdure stocke. Les paramtres et leur type, s'il y en as suivent le nom. L'entte se termine par le mot clef AS. Exemple :
C R E A T EP R O C E D U R ES P _ S E A R C H _ S T R I N G _ A N Y F I E L D @ T a b l e N a m e V a r c h a r ( 1 2 8 ) , -n o md el at a b l ep a s s e na r g u m e n t @ S e a r c h W o r dV a r c h a r ( 3 2 ) -m o tr e c h e r c h A S . . .

4.2. Paramtres, variables de retour et ensemble de donnes

Une procdure stocke peut accepter de 0 1024 paramtres (arguments). Elle a toujours une valeur de retour qui par dfaut est le code d'excution (entier v succs). Elle peut retourner des lignes de table comme une requte. Pour dclarer les paramtres il faut les lister avec un nom de variable et un type. Par dfaut les paramtres sont des paramtres d'entre. Comme pour toutes les listes le sparateur est la virgule. On peut dclarer des valeurs par dfaut et spcifier si le paramtre est en sortie avec le mot clef OUTPUT. Exemple :

sqlpro.developpez.com/cours/sqlserver/transactsql/

9/29

C R E A T EP R O C E D U R ES P _ S Y S _ D B _ T R A N S A C T I O N @ T R A N S _ N U MI N T E G E R , -n u m r od el at r a n s a c t i o nc o n c e r n e @ O KB I T=0O U T P U T -r e t o u r0O K ,1p r o b l m e A S . . .

Pour rcuprer la valeur de d'un paramtre OUTPUT il faut prciser une variable de rcupration de nature OUTPUT dans le lacement de l'excution. Exemple :
D E C L A R E@ R e t o u r O Kb i t E X E C ( S P _ S Y S _ D B _ T R A N S A C T I O N1 2 7 ,@ R e t o u r O KO U T P U T ) S E L E C T@ R e t o u r O K

Un paramtre de type CURSOR (curseur) est un cas particulier et ne peut tre utilis qu'en sortie et conjointement au mot clef VARYING qui spcifie que sa dfinition connue au moment de la compilation (le nombre et le type des colonnes n'est pas dfini cet instant).
C R E A T EP R O C E D U R ES E A R C H _ T E X T@ r e s u l t T a b l eC U R S O RV A R Y I N GO U T P U T A S

Un tel paramtre peut tre rutilis dans une autre procdure stock ou dans un trigger.

Comme nous l'avons vu, toute procdure stocke renvoie une variable de type entier pour signaler son tat. Si cette variable vaut 0, la procdure s'est droule sa autre valeur indique un problme. Les valeurs de 0 -99 sont rserves et celles de 0 -14 sont prdfinies. Par exemple la valeur -5 signifie erreur de syntaxe. Bien assigner une valeur de retour de procdure l'aide de l'instruction RETURN. Une procdure stocke peut en outre renvoyer un jeu de rsultat sous la forme d'un ensemble de donnes la manire des rsultats de requte. Exemple :
C R E A T EP R O C E D U R ES P _ L I S T E _ C L I E N T @ C L I _ I D _ D E B U TI N T E G E R ,@ C L I _ I D _ F I NI N T E G E R A S S E L E C T' -d b u td el i s t ec l i e n t' U N I O N A L L S E L E C TC L I _ N O M F R O M T _ C L I E N T W H E R E C L I _ I DB E T W E E N@ C L I _ I D _ D E B U TA N D@ C L I _ I D _ F I N U N I O N A L L S E L E C T' - f i nd el i s t ec l i e n t '

4.3. Gestion des erreurs

Il existe diffrents niveaux d'erreurs et diffrents moyens de les grer. Considrons une procdure stocke qui aurait pour effet de supprimer une ligne d'une table en s'assurant de supprimer pralablement toutes les lignes de tous concerns. L'entte d'une telle procdure pourrait s'crire :
C R E A T EP R O C E D U R ES P _ D E L E T E _ C L I E N T _ R E C U R S I V E @ C L I _ I DI N T E G E R

Si la ligne considre n'est pas retrouve dans la table des clients, comme si la valeur du paramtre est NULL, cette procdure chouera sans indiquer d'anom procder des tests pralables (nullit, existence). Sans cela on dit que l'on une "exception silencieuse".

Pour les exceptions plus flagrantes, SQL Server fournit la variable globale @@error que l'on peut tester tout instant. Cette variable est mise jour chaque instru Le code continue de s'excuter mme aprs une erreur.

Pour grer les erreurs, SQL Server dispose de la leve des erreurs l'aide de l'instruction RAISERROR et l'utilisation du GOTO combin une tiquette de branchem sur erreur, permet de centraliser la gestion des erreurs un seul et mme endroit du programme. Voici un exemple mettant en uvre ces principes :
/ * \ |r e c h e r c h ed ' u n eo c c u r r e n c ed em o td a n sn ' i m p o r t e | |q u e l l ec o l o n n ed et y p ec a r a c t r e sd ' u n et a b l ed o n n e| | -| |F r d r i cB R O U A R D-C O M M U N I C A T I CS A-2 0 0 1 1 2 1 7 | \ -* / C R E A T EP R O C E D U R ES P _ S E A R C H _ S T R I N G _ A N Y F I E L D @ T a b l e N a m eV a r c h a r ( 1 2 8 ) , -n o md el at a b l ep a s s e na r g u m e n t @ S e a r c h W o r dV a r c h a r ( 3 2 ) -m o tr e c h e r c h A S I F@ T a b l e N a m eI SN U L LO R@ S e a r c h W o r dI SN U L L R A I S E R R O R( ' P a r a m t r e sN U L Li m p o s s i b l et r a i t e r ' ,1 6 ,1 ) I F@ @ E R R O R< >0G O T OL B L _ E R R O R -t e s td ' e x i s t e n c ed el at a b l e I FN O TE X I S T S ( S E L E C T* F R O M I N F O R M A T I O N _ S C H E M A . t a b l e s W H E R E T A B L E _ N A M E=@ T a b l e N a m e ) R A I S E R R O R( ' R f r e n c e sd et a b l ei n c o n n u e% s ' ,1 6 ,1 ,@ T a b l e N a m e ) I F@ @ E R R O R< >0G O T OL B L _ E R R O R D e c l a r e@ C o l u m n L i s tv a r c h a r ( 1 0 0 0 ) D e c l a r e@ S Q Lv a r c h a r ( 1 2 0 0 ) -l i s t ed e sn o m sd ec o l o n n e sd a n s -l e s q u e l sl ar e c h e r c h ev as ' e f f e c t u e r -r e q u t ed er e c h e r c h e

-o b t e n t i o nd el al i s t ed e sc o l o n n e sp o u rl ar e q u t ed er e c h e r c h e S E L E C T@ C o l u m n L i s t=C O A L E S C E ( @ C o l u m n L i s t+'+C O A L E S C E ( ' ,' C O A L E S C E ( ' )+c o l u m n _ n a m e+ ' ,' ' ' ' ) ' F R O M I N F O R M A T I O N _ S C H E M A . C O L U M N S W H E R E T A B L E _ N A M E=@ T a b l e N a m e A N D D A T A _ T Y P EL I K E' % c h a r % '

sqlpro.developpez.com/cours/sqlserver/transactsql/

10/29

I F@ C o l u m n L i s tI SN U L L R A I S E R R O R( ' A u c u n ec o l o n n ed er e c h e r c h et r o u v d a n sl at a b l e% s ' , 1 6 ,1 ,@ T a b l e N a m e ) I F@ @ E R R O R< >0G O T OL B L _ E R R O R P R I N T' I N F O-@ C o l u m n L i s tv a l u ei s:'+@ C o l u m n L i s t -a s s e m b l a g ed ut e x t ed el ar e q u t ed er e c h e r c h e S e t@ S Q L= ' S E L E C T*F R O M' +@ T a b l e N a m e +'W H E R E' +@ C o l u m n L i s t +'L I K E' ' % ' +@ S e a r c h W o r d+ ' % ' ' ' P R I N T' I N F O-@ S Q Lv a l u ei s:'+@ S Q L -e x c u t i o nd el ar e q u t ed er e c h e r c h e E x e c( @ S Q L ) R E T U R N L B L _ E R R O R : P R I N T' E R R E U RL O R SD EL ' ' E X C U T I O ND EL AP R O C D U R ES T O C K ES P _ S E A R C H _ S T R I N G _ A N Y F I E L D '

4.4. Procdures stockes prdfinies

SQL Server possde des procdures stockes pr tablies, un peu la manire d'une bibliothque d'utilisation. Elles servent essentiellement l'administration (gesti et des bases) et l'information (dictionnaire des donnes). Elle se situent toutes dans la base "master". Ainsi, la procdure stocke "sp_help" fournit une description de n'importe quel objet de la base. Pour appeler de telles procdures, il n'est pas ncessaire de prciser le nom de la base "master", ce nom est implicite. Ces procdures stockes permettent : de piloter le paramtrage du serveur et de la base de donnes (respect des normes SQL 2, maximum d'utilisateurs) - exemple : sp_configure de dfinir les objets de la base (table, index, contraintes, vues) - exemple : sp_addtype d'administrer le serveur, les bases, les accs (rles, utilisateurs, login) - exemple : sp_droplogin d'obtenir de l'aide et de la documentation (aide en ligne, explications) - exemple : sp_helpsort de grer les agents (alertes et batch) - exemple : sp_add_job d'assurer les rplications (entre bases et serveurs) - exemple : sp_deleteMergeConflictRows de monitorer le fonctionnement de SQL Server (tracer l'excution) - exemple : xp_sqlTrace ... Nota : des procdures stockes dites tendues (dont le nom commence gnralement par "xp_") font appel du code C sous forme de DLL. Exemple : lancer un programme en ligne de commande depuis SQL Server (procdure dont l'utilisation est dconseiller !) Exemple - cration d'un type utilisateur (DOMAINE SQL 2) pour spcification numrique de la valeur d'un mois avec contrle de validit :
-a j o u td ut y p eT T _ M O N T He ne n t i e ro b l i g a t o i r e S P _ a d d T y p eT T _ M O N T H ,' I N T E G E R ' ,' N O TN U L L ' -c r e a t i o nd el ar g l eR _ C H E C K _ M O N T Hv r i f i a n t -q u el av a l e u rs o i tc o m p r i s ee n t r e1e t1 2 C R E A T ER U L ER _ C H E C K _ M O N T HA S@ v a l u eB E T W E E N1A N D1 2 -l i a i s o nd el ar g l ea ut y p e S P _ b i n d R u l eR _ C H E C K _ M O N T H ,T T _ M O N T H

4.5. Verrouillage

Le verrouillage est la technique de base pour assurer les concurrences d'accs aux ressources. On peut observer les verrous poss lors des manipulations de donnes l'aide de la procdure stocke sp_lock. De mme on peut savoir qui utilise quoi l'aid stocke sp_who. SQL Server pose en principe les bons verrous lors des requtes. Mais il peut arriver que l'on souhaite : soit se dbarrasser des contraintes de verrouillage, notamment pour faire du "dirty read" (lecture sale) soit poser des verrous plus contraignant pour s'assurer du traitement Dans les deux cas il faut complter les ordre SQL par une description des verrous attendus. Voici les paramtres de verrouillage que l'on peut spcifier : Verrou NOLOCK HOLDLOCK UPDLOCK PAGLOCK TABLOCK aucun verrou maintient du verrou jusqu' la fin de la transaction pose un verrou de mise jour au lieu d'un verrou partag force la pose d'un verrou de page force un verrou partag sur la table SELECT impossible pas ncessaire redondant force la pose d'un verrou de page force un verrou exclusif sur la table UPDATE

force un verrou exclusif sur la table pendant toute la dure force un verrou exclusif sur la table pendan TABLOCKX de la transaction de la transaction Ces paramtres se prcisent dans un ordre SQL aprs le nom de la table et le mot clef WITH en utilisant le parenthsage. Exemples : Acclration d'une extraction de donnes en demandant la suppression du verrouillage :
S E L E C T* F R O M T _ C L I E N TCW I T H( N O L O C K ) J O I NT _ F A C T U R EFW I T H( N O L O C K )

sqlpro.developpez.com/cours/sqlserver/transactsql/

11/29

O NC . C L I _ I D=F . C L I _ I D

Verrouillage exclusif de la table le temps de la mise jour :


U P D A T ET _ C L I E N TW I T H( T A B L O C K ) S E TC L I _ N O M=R E P L A C E ( C L I _ N O M ,'' ,' ' )

On peut combiner certains paramtres de verrouillage. Exemple :


. . .W I T H( P A G L O C KH O L D L O C K ). . .

Attention : la manipulation des verrous est affaire de spcialistes. Une pose de verrous sans tude pralable de la concurrence d'excution des diffrentes procdur base, peut conduire des scnarios de blocage, comme "l'treinte fatale".

4.6. Gestion de transactions


Toute ordre SQL du DML est une transaction (SELECT INSERT, UPDATE, DELETE). Parce que SQL Server fonctionne en "AUTOCOMMIT", une combinaison de diffrents ordres ncessite la pose explicite d'une transaction. Ceci se fait par l'instruction BEGIN TRANSACTION et doit tre termin soit par un ROLLBACK, soit par un COMMIT. Une transaction peut tre anonyme ou nomme. De toute faon SQL Server lui attribue un identifiant interne unique. Exemple simple. Il s'agit de rserver 3 place dans le vol AF714 pour le client 123, s'il y a bien de la place pour ce vol !
B E G I NT R A N S A C T I O N -r e s t et i ld el ap l a c ep o u rc ev o l? I FN O TE X I S T S ( S E L E C T* F R O M T _ V O L _ A V I O N W H E R E V O L _ R E F=' A F 7 1 4 ' A N D V O L _ P L A C E _ L I B R E>3 ) T H E N B E G I N R O L L B A C KT R A N S A C T I O N R E T U R N E N D -d c o m p t ed e sp l a c e sv e n d u e s U P D A T ET _ V O L _ A V I O N S E T V O L _ P L A C E _ L I B R E =V O L _ P L A C E _ L I B R E-3 W H E R E V O L _ R E F=' A F 7 1 4 ' I F( @ @ E R R O R< >0 )O R( @ @ R O W C O U N T=0 ) G O T OR O L L B A C K _ O N _ E R R O R -g n r a t i o nd ' u n er s e r v a t i o n I N S E R TI N T OT _ R E S E R V A T I O N( V O L _ R E F ,C L I _ I D ,P L A C E S ) V A L U E S( ' A F 7 1 4 ' ,1 2 3 ,3 ) I F( @ @ E R R O R< >0 )O R( @ @ R O W C O U N T=0 ) G O T OR O L L B A C K _ O N _ E R R O R -v a l i d a t i o nd el ' e n s e m b l e C O M M I TT R A N S A C T I O N R E T U R N -s ib r a n c h e m e n tl ' t i q u e t t ed ' e r r e u ra l o r sR O L L B A C K R O L L B A C K _ O N _ E R R O R : R O L L B A C KT R A N S A C T I O N

SQL Server permet aussi de dfinir des points de sauvegarde, que l'on peut considrer comme un validation partielle d'une transaction. Pour dfinir un point de utiliser l'instruction SAVE TRANSACTION avec un nom de prfrence (pas obligatoire). Par consquent pour faire un ROLLBACK partiel il suffit de prciser le nom du point de sauvegarde dans l'ordre ROLLBACK. L'utilisation de la variable @@TranCount permet de savoir le nombre de transaction ouvertes en cours.

Une bonne transaction ne saurait tre bien gre sans une apprciation claire du niveau d'isolation. SQL Server gre les 4 niveaux de la norme SQL 2. L TRANSACTION ISOLATION LEVEL dont les options sont READ COMMITTED, READ UNCOMMITTED, REPEATABLE READ et SERIALIZABLE permet de dfinir le d'une transaction. Niveau Effets Implmente la lecture incorrecte, ou le verrouillage de niveau 0, ce qui signifie qu'aucun verrou partag n'est gnr et qu'aucun verrou exclusif n'est respect. Lorsque cette option est active, il est possible de lire des donnes non valides, ou donnes incorrectes ; les valeurs des donnes peuvent tre modifies et des lignes 0 peuvent apparatre ou disparatre dans le jeu de donnes avant la fin de la transaction. Cette option a le mme effet que l'activation de l'option NOLOCK dans toutes les tables de toutes les instructions SELECT d'une transaction. Il s'agit du niveau d'isolation le moins restrictif parmi les quatre disponibles. Spcifie que les verrous partags sont maintenus durant la lecture des donnes pour viter des lectures incorrectes. Les donnes peuvent nanmoins tre modifies avant la fin 1 de la transaction, ce qui donne des lectures non renouveles ou des donnes fantmes. Cette option est l'option SQL Server par dfaut. Des verrous sont placs dans toutes les

R E A DU N C O M M I T T E D

R E A DC O M M I T T E D

sqlpro.developpez.com/cours/sqlserver/transactsql/

12/29

R E P E A T A B L ER E A D

donnes utilises dans une requte, afin d'empcher les autres utilisateurs de les mettre jour. Toutefois, un autre utilisateur peut ajouter de nouvelles lignes fantmes dans un jeu de donnes par un utilisateur ; celles-ci seront incluses dans des lectures ultrieures dans la transaction courante.

Place un verrou sur une plage de donnes, empchant les autres utilisateurs de les mettre jour ou d'insrer des lignes dans le jeu de donnes, jusqu' la fin de la transaction. Il s'agit du niveau d'isolation le plus restrictif parmi les quatre niveaux S E R I A L I Z A B L E disponibles. Utilisez cette option uniquement 3 lorsque cela s'avre ncessaire, car la concurrence d'accs est moindre. Cette option a le mme effet que l'utilisation de l'option HOLDLOCK dans toutes les tables de toutes les instructions SELECT d'une transaction. Attention : par dfaut SQL Server travaille au niveau READ COMMITTED. Ceci explique sa rapidit compare a des serveurs qui fonctionnent par dfaut au niveau mais peut s'avrer catastrophique pour l'intgit des donnes !!!

CONSEIL : il est toujours prfrable d'utiliser la gestion des transactions que de manipuler les verrous, sauf en ce qui concerne la "lecture sale" notamment da utilisation client/serveur en mode dconnect (par exemple dans le cadre de restitutions documentaires pour un site web). NOTA : SQL Server permet de grer des transactions distribues et gre le "commit deux phases" mais sans permettre l'utilisation de points de sauvegarde. Exemple : gestion d'un arbre modlis par intervalle

Pour une illustration plus complte des procdures stockes nous allons montrer les diffrentes procdures ncessaires pour faire "fonctionner" un arbre mo intervallaire. Pour une dveloppement plus complet de ce sujet, lire l'article sur la reprsentation intervallaire des arborescences

Dans notre cas nous allons considrer une table permettant de grer le dveloppement des projet d'une entreprise. Voici la table du dveloppement. Elle contient l chaque noeuds, y compris son identifiant, sojn libell, ses bornes droite et gauche et son niveau :
C R E A T ET A B L ET _ D E V E L O P P E M E N T _ D E V ( D E V _ I D I N T E G E RI D E N T I T Y( 1 ,1 )N O TN U L L, D E V _ N I V E A U S M A L L I N T N O TN U L L, D E V _ L I B E L L E C H A R( 3 2 ) N O TN U L L, D E V _ B O R N E _ G A U C H EI N T E G E R N O TN U L L, D E V _ B O R N E _ D R O I T EI N T E G E R N O TN U L L )

-i d e n t i f i a n t -n i v e a ud un o e u d -l i b e l l -b o r n eg a u c h ed el ' a r b r e -b o r n ed r o i t ed el ' a r b r e

Tout d'abord voici la procdure d'insertion d'un fils ain, c'est dire d'un fils qui sera le plus proche du sommet au moment de l'insertion. On passe la procdure l'id pre et le libell. Une variable de retour permet de conatre l'tat de l'insertion.
C R E A T EP R O C E D U R ES P _ D E V _ I N S E R T I O N _ A R B R E _ F I L S _ A I N E @ i d _ p e r ei n t e g e r , @ l i b e l l ev a r c h a r ( 3 2 ) , @ i d _ i n s i n t e g e rO U T P U TA S -F r d r i cB R O U A R D1 7 / 1 1 / 2 0 0 1 -i n s e r t i o ns o u sp r ed a n sl ' a r b r ed ud v e l o p p e m e n t -p a r a m t r e s:i d _ p e r e ,l i b e l l e D E C L A R E@ b g _ p e r ei n t e g e r D E C L A R E@ n i v e a ui n t e g e r D E C L A R E@ O Ki n t e g e r S E TN O C O U N TO N -d m a r r a g et r a n s a c t i o n S E TT R A N S A C T I O NI S O L A T I O NL E V E LS E R I A L I Z A B L E B E G I NT R A N S A C T I O NI N S E R T _ T R E E _ F I L S _ A I N E -v r i f i c a t i o nd el ' e x i s t e n c ed up r e S E L E C T@ O K=c o u n t ( * ) F R O MT _ D E V E L O P P E M E N T _ D E V W H E R ED E V _ I D=@ i d _ p e r e -s i l m e n ts u p p r i m ,a l o r sr e t o u rs a n si n s e r t i o na v e cv a l e u r1 I F@ O K=0 B E G I N S E L E C T1 R O L L B A C KT R A N S A C T I O NI N S E R T _ T R E E _ F I L S _ A I N E R E T U R N E N D -r e c h e r c h ed ub g _ p e r ee tc a l c u ld un i v e a ui n f r i e u r S E L E C T@ b g _ p e r e=D E V _ B O R N E _ G A U C H E ,@ n i v e a u=D E V _ N I V E A U+1 F R O MT _ D E V E L O P P E M E N T _ D E V W H E R ED E V _ I D=@ i d _ p e r e -d c a l a g ep o u ri n s e r t i o nb o r n ed r o i t e U P D A T ET _ D E V E L O P P E M E N T _ D E V S E TD E V _ B O R N E _ D R O I T E=D E V _ B O R N E _ D R O I T E+2 W H E R ED E V _ B O R N E _ D R O I T E>@ b g _ p e r e I F@ @ E R R O R< > 0 B E G I N R O L L B A C KT R A N S A C T I O NI N S E R T _ T R E E _ F I L S _ A I N E S E L E C T1 R E T U R N E N D -d c a l a g ep o u ri n s e r t i o nb o r n eg a u c h e U P D A T ET _ D E V E L O P P E M E N T _ D E V S E TD E V _ B O R N E _ G A U C H E=D E V _ B O R N E _ G A U C H E+2 W H E R ED E V _ B O R N E _ G A U C H E>@ b g _ p e r e

sqlpro.developpez.com/cours/sqlserver/transactsql/

13/29

I F@ @ E R R O R< > 0 B E G I N R O L L B A C KT R A N S A C T I O NI N S E R T _ T R E E _ F I L S _ A I N E S E L E C T1 R E T U R N E N D -i n s e r t i o n I N S E R TI N T OT _ D E V E L O P P E M E N T _ D E V( D E V _ N I V E A U ,D E V _ L I B E L L E ,D E V _ B O R N E _ G A U C H E ,D E V _ B O R N E _ D R O I T E ) V A L U E S( @ n i v e a u ,@ l i b e l l e ,@ b g _ p e r e+1 ,@ b g _ p e r e+2 ) S E L E C T@ i d _ i n s=@ @ i d e n t i t y I F@ @ E R R O R< > 0 B E G I N R O L L B A C KT R A N S A C T I O NI N S E R T _ T R E E _ F I L S _ A I N E S E L E C T1 R E T U R N E N D C O M M I TT R A N S A C T I O NI N S E R T _ T R E E _ F I L S _ I A N E S E L E C T@ i d _ i n s -r e n v o i ed el ' i d e n t i f i a n td el ' l m e n ti n s r .

Pour le fils cadet, la procdure n'est pas plus complique :


C R E A T EP R O C E D U R ES P _ D E V _ I N S E R T I O N _ A R B R E _ F I L S _ C A D E T @ i d _ p e r ei n t e g e r , @ l i b e l l ev a r c h a r ( 3 2 ) , @ i d _ i n s i n t e g e r O U T P U TA S -F r d r i cB R O U A R D1 7 / 1 1 / 2 0 0 1 -i n s e r t i o ns o u sp r ed a n sl ' a r b r ed ud v e l o p p e m e n t -p a r a m t r e s:i d _ p e r e ,l i b e l l e D E C L A R E@ b d _ p e r ei n t e g e r D E C L A R E@ n i v e a ui n t e g e r D E C L A R E@ O Ki n t e g e r S E TN O C O U N TO N -o ng r eu n et r a n s a c t i o nq u ir e m a n i el e sb o r n e sd el ' a r b r e . -i ln ef a u tp a s t r e' d r a n g 'p a rd ' a u t r e su t i l i s a t e u r sc o n c u r r e n t sp e n d a n tc e t t em a n o e u v r e S E TT R A N S A C T I O NI S O L A T I O NL E V E LS E R I A L I Z A B L E B E G I NT R A N S A C T I O NI N S E R T _ T R E E _ F I L S _ C A D E T -v r i f i c a t i o nd el ' e x i s t e n c ed up r e S E L E C T@ O K=c o u n t ( * ) F R O MT _ D E V E L O P P E M E N T _ D E V W H E R ED E V _ I D=@ i d _ p e r e -s i l m e n ts u p p r i m ,a l o r sr e t o u rs a n si n s e r t i o na v e cv a l e u r1 I F@ O K=0 B E G I N S E L E C T1 R O L L B A C KT R A N S A C T I O NI N S E R T _ T R E E _ F I L S _ C A D E T R E T U R N E N D -r e c h e r c h ed ub g _ p e r ee tc a l c u ld un i v e a ui n f r i e u r S E L E C T@ b d _ p e r e=D E V _ B O R N E _ D R O I T E ,@ n i v e a u=D E V _ N I V E A U+1 F R O MT _ D E V E L O P P E M E N T _ D E V W H E R ED E V _ I D=@ i d _ p e r e -d c a l a g ep o u ri n s e r t i o nb o r n ed r o i t e U P D A T ET _ D E V E L O P P E M E N T _ D E V S E TD E V _ B O R N E _ D R O I T E=D E V _ B O R N E _ D R O I T E+2 W H E R ED E V _ B O R N E _ D R O I T E> =@ b d _ p e r e I F@ @ E R R O R< > 0 B E G I N R O L L B A C KT R A N S A C T I O NI N S E R T _ T R E E _ F I L S _ C A D E T S E L E C T1 R E T U R N E N D -d c a l a g ep o u ri n s e r t i o nb o r n eg a u c h e U P D A T ET _ D E V E L O P P E M E N T _ D E V S E TD E V _ B O R N E _ G A U C H E=D E V _ B O R N E _ G A U C H E+2 W H E R ED E V _ B O R N E _ G A U C H E>@ b d _ p e r e I F@ @ E R R O R< > 0 B E G I N R O L L B A C KT R A N S A C T I O NI N S E R T _ T R E E _ F I L S _ C A D E T S E L E C T1 R E T U R N E N D -i n s e r t i o n I N S E R TI N T OT _ D E V E L O P P E M E N T _ D E V( D E V _ N I V E A U ,D E V _ L I B E L L E ,D E V _ B O R N E _ G A U C H E ,D E V _ B O R N E _ D R O I T E ) V A L U E S( @ n i v e a u ,@ l i b e l l e ,@ b d _ p e r e,@ b d _ p e r e+1 ) S E L E C T@ i d _ i n s=@ @ i d e n t i t y I F@ @ E R R O R< > 0 B E G I N R O L L B A C KT R A N S A C T I O NI N S E R T _ T R E E _ F I L S _ C A D E T S E L E C T1a sI D R E T U R N E N D C O M M I TT R A N S A C T I O NI N S E R T _ T R E E _ S O N

sqlpro.developpez.com/cours/sqlserver/transactsql/

14/29

S E L E C T@ i d _ i n s

Voici maintenant comment on insre un frre droite d'un autre :


C R E A T EP R O C E D U R ES P _ D E V _ I N S E R T I O N _ A R B R E _ F R E R E _ D R O I T @ i d _ f r e r ei n t e g e r , @ l i b e l l e v a r c h a r ( 3 2 ) , @ i d _ i n s i n t e g e r O U T P U TA S -F r d r i cB R O U A R D1 7 / 1 1 / 2 0 0 1 -i n s e r t i o nl a t r a l ed r o i t ed uf r r e -p a r a m t r e s:i d _ f r e r e ,l i b e l l e D E C L A R E@ b d _ f r e r ei n t e g e r D E C L A R E@ n i v e a ui n t e g e r D E C L A R E@ O Ki n t e g e r S E TN O C O U N TO N -d m a r r a g et r a n s a c t i o n S E TT R A N S A C T I O NI S O L A T I O NL E V E LS E R I A L I Z A B L E B E G I NT R A N S A C T I O NI N S E R T _ T R E E _ R I G H T -v r i f i ed el ' e x i s t e n c ed uf r r e S E L E C T@ O K=c o u n t ( * ) F R O MT _ D E V E L O P P E M E N T _ D E V W H E R ED E V _ I D=@ i d _ f r e r e -s i l m e n ts u p p r i m ,a l o r sr e t o u rs a n si n s e r t i o na v e cv a l e u r1 I F@ O K=0 B E G I N S E L E C T1 R O L L B A C KT R A N S A C T I O NI N S E R T _ T R E E _ R I G H T R E T U R N E N D -r e c h e r c h ed ub d _ f r e r ee td un i v e a u S E L E C T@ b d _ f r e r e=D E V _ B O R N E _ D R O I T E ,@ n i v e a u=D E V _ N I V E A U F R O MT _ D E V E L O P P E M E N T _ D E V W H E R ED E V _ I D=@ i d _ f r e r e -d c a l a g eb o r n eg a u c h ep o u ri n s e r t i o n U P D A T ET _ D E V E L O P P E M E N T _ D E V S E T D E V _ B O R N E _ G A U C H E=D E V _ B O R N E _ G A U C H E+2 W H E R E D E V _ B O R N E _ G A U C H E>@ b d _ f r e r e I F@ @ E R R O R< > 0 B E G I N R O L L B A C KT R A N S A C T I O N I N S E R T _ T R E E _ R I G H T S E L E C T1 R E T U R N E N D -d c a l a g eb o r n ed r o i t ep o u ri n s e r t i o n U P D A T ET _ D E V E L O P P E M E N T _ D E V S E TD E V _ B O R N E _ D R O I T E=D E V _ B O R N E _ D R O I T E+2 W H E R ED E V _ B O R N E _ D R O I T E>@ b d _ f r e r e I F@ @ E R R O R< > 0 B E G I N R O L L B A C KT R A N S A C T I O N I N S E R T _ T R E E _ R I G H T S E L E C T1 R E T U R N E N D -i n s e r t i o n I N S E R TI N T OT _ D E V E L O P P E M E N T _ D E V( D E V _ N I V E A U ,D E V _ L I B E L L E ,D E V _ B O R N E _ G A U C H E ,D E V _ B O R N E _ D R O I T E ) V A L U E S( @ n i v e a u ,@ l i b e l l e ,@ b d _ f r e r e+1 ,@ b d _ f r e r e + 2 ) S E L E C T@ i d _ i n s=@ @ i d e n t i t y I F@ @ E R R O R< > 0 B E G I N R O L L B A C KT R A N S A C T I O N I N S E R T _ T R E E _ R I G H T S E L E C T1 R E T U R N E N D C O M M I TT R A N S A C T I O NI N S E R T _ T R E E _ R I G H T S E L E C T@ i d _ i n s

Mme insertion en frre gauche :


C R E A T EP R O C E D U R ES P _ D E V _ I N S E R T I O N _ A R B R E _ F R E R E _ G A U C H E @ i d _ f r e r ei n t e g e r , @ l i b e l l e v a r c h a r ( 3 2 ) , @ i d _ i n s i n t e g e rO U T P U TA S -F r d r i cB R O U A R D1 7 / 1 1 / 2 0 0 1 -i n s e r t i o nl a t r a l eg a u c h ed uf r r e -p a r a m t r e s:i d _ f r e r e ,l i b e l l e D E C L A R E@ b g _ f r e r ei n t e g e r D E C L A R E@ n i v e a ui n t e g e r D E C L A R E@ O Ki n t e g e r S E TN O C O U N TO N S E TT R A N S A C T I O NI S O L A T I O NL E V E LS E R I A L I Z A B L E B E G I NT R A N S A C T I O NI N S E R T _ T R E E _ L E F T -v r i f i c a t i o nd el ' e x i s t e n c ed uf r r e

sqlpro.developpez.com/cours/sqlserver/transactsql/

15/29

S E L E C T@ O K=c o u n t ( * ) F R O MT _ D E V E L O P P E M E N T _ D E V W H E R ED E V _ I D=@ i d _ f r e r e -s i l m e n ts u p p r i m ,a l o r sr e t o u rs a n si n s e r t i o na v e cv a l e u r1 I F@ O K=0 B E G I N S E L E C T1 R O L L B A C KT R A N S A C T I O NI N S E R T _ T R E E _ L E F T R E T U R N E N D -r e c h e r c h ed ub g _ f r e r e S E L E C T@ b g _ f r e r e=D E V _ B O R N E _ G A U C H E ,@ n i v e a u=D E V _ N I V E A U F R O MT _ D E V E L O P P E M E N T _ D E V W H E R ED E V _ I D=@ i d _ f r e r e -d c a l a g eb o r n eg a u c h ep o u ri n s e r t i o n U P D A T ET _ D E V E L O P P E M E N T _ D E V S E T D E V _ B O R N E _ G A U C H E=D E V _ B O R N E _ G A U C H E+2 W H E R ED E V _ B O R N E _ G A U C H E> =@ b g _ f r e r e I F@ @ E R R O R< > 0 B E G I N R O L L B A C KT R A N S A C T I O NI N S E R T _ T R E E _ L E F T S E L E C T1 R E T U R N E N D -d c a l a g eb o r n ed r o i t ep o u ri n s e r t i o n U P D A T ET _ D E V E L O P P E M E N T _ D E V S E TD E V _ B O R N E _ D R O I T E=D E V _ B O R N E _ D R O I T E+2 W H E R ED E V _ B O R N E _ D R O I T E>@ b g _ f r e r e I F@ @ E R R O R< > 0 B E G I N R O L L B A C KT R A N S A C T I O NI N S E R T _ T R E E _ L E F T S E L E C T1 R E T U R N E N D -i n s e r t i o n I N S E R TI N T OT _ D E V E L O P P E M E N T _ D E V( D E V _ N I V E A U ,D E V _ L I B E L L E ,D E V _ B O R N E _ G A U C H E ,D E V _ B O R N E _ D R O I T E ) V A L U E S( @ n i v e a u ,@ l i b e l l e ,@ b g _ f r e r e ,@ b g _ f r e r e + 1 ) S E L E C T@ i d _ i n s=@ @ i d e n t i t y I F@ @ E R R O R< > 0 B E G I N R O L L B A C KT R A N S A C T I O N S E L E C T1 R E T U R N E N D C O M M I TT R A N S A C T I O NI N S E R T _ T R E E _ L E F T S E L E C T@ i d _ i n s

Enfin, comment supprimer. Notez l'argument "rcursif" pass en paramtre de procdure pour spcifier si l'on tue toute la ligne ou si l'on laisse survivre les descenda
C R E A T EP R O C E D U R ES P _ D E V _ S U P P R E S S I O N @ i d _ e l e m e n ti n t e g e r , @ r e c u r s i f b i t A S -F r d r i cB R O U A R D2 0 / 1 1 / 2 0 0 1 -s u p p r e s s i o nd ' u n l m e n t( @ r e c u r s i f=0 )o ud ' u ns o u sa r b r e( @ r e c u r s i f=1 ) -p a r a m t r e s:i d _ e l e m e n t ,@ r e c u r s i f D E C L A R E@ O Ki n t e g e r D E C L A R E@ b g _ e l e m e n ti n t e g e r D E C L A R E@ b d _ e l e m e n ti n t e g e r D E C L A R E@ i n t e r v a l l ei n t e g e r

S E TN O C O U N TO N -d m a r r a g et r a n s a c t i o n S E TT R A N S A C T I O NI S O L A T I O NL E V E LS E R I A L I Z A B L E B E G I NT R A N S A C T I O ND E L E T E _ T R E E -v r i f i ed el ' e x i s t e n c ed el ' l m e n t S E L E C T@ O K=c o u n t ( * ) F R O MT _ D E V E L O P P E M E N T _ D E V W H E R ED E V _ I D=@ i d _ e l e m e n t -s i l m e n ts u p p r i m ,a l o r sr e t o u rs a n si n s e r t i o na v e cv a l e u r1 I F@ O K=0 B E G I N S E L E C T1 R O L L B A C KT R A N S A C T I O ND E L E T E _ T R E E R E T U R N E N D

-r e c h e r c h ed e sb d _ e l e m e n te tb d _ e l e m e n t S E L E C T@ b d _ e l e m e n t=D E V _ B O R N E _ D R O I T E ,@ b g _ e l e m e n t=D E V _ B O R N E _ G A U C H E F R O MT _ D E V E L O P P E M E N T _ D E V W H E R ED E V _ I D=@ i d _ e l e m e n t I F@ r e c u r s i f=0 B E G I N -s u p p r e s s i o nd el ' l m e n t

sqlpro.developpez.com/cours/sqlserver/transactsql/

16/29

D E L E T EF R O MT _ D E V E L O P P E M E N T _ D E V W H E R E D E V _ I D=@ i d _ e l e m e n t I F@ @ E R R O R< > 0 B E G I N R O L L B A C KT R A N S A C T I O N D E L E T E _ T R E E S E L E C T1 R E T U R N E N D -d c a l a g ed e sb o r d sd r o i t se tg a u c h e sd e s l m e n t sd us o u sa r b r e U P D A T ET _ D E V E L O P P E M E N T _ D E V S E TD E V _ B O R N E _ D R O I T E=D E V _ B O R N E _ D R O I T E-1 , D E V _ B O R N E _ G A U C H E=D E V _ B O R N E _ G A U C H E-1 W H E R ED E V _ B O R N E _ G A U C H E>@ b g _ e l e m e n tA N DD E V _ B O R N E _ D R O I T E<@ b d _ e l e m e n t I F@ @ E R R O R< > 0 B E G I N R O L L B A C KT R A N S A C T I O N D E L E T E _ T R E E S E L E C T1 R E T U R N E N D -d c a l a g ed e sb o r d sg a u c h e sd e s l m e n t se x t e r n e sa us o u sa r b r e U P D A T ET _ D E V E L O P P E M E N T _ D E V S E T D E V _ B O R N E _ G A U C H E=D E V _ B O R N E _ G A U C H E-2 W H E R E D E V _ B O R N E _ G A U C H E>@ b g _ e l e m e n t I F@ @ E R R O R< > 0 B E G I N R O L L B A C KT R A N S A C T I O N D E L E T E _ T R E E S E L E C T1 R E T U R N E N D -d c a l a g ed e sb o r d sd r o i t sd e s l m e n t se x t e r n e sa us o u sa r b r e U P D A T ET _ D E V E L O P P E M E N T _ D E V S E T D E V _ B O R N E _ D R O I T E=D E V _ B O R N E _ D R O I T E-2 W H E R E D E V _ B O R N E _ D R O I T E<@ b g _ e l e m e n t I F@ @ E R R O R< > 0 B E G I N R O L L B A C KT R A N S A C T I O N D E L E T E _ T R E E S E L E C T1 R E T U R N E N D E N D I F@ r e c u r s i f=1 B E G I N -s u p p r e s s i o nd e s l m e n t sd us o u sa r b r e D E L E T EF R O MT _ D E V E L O P P E M E N T _ D E V W H E R E D E V _ B O R N E _ G A U C H E> =@ b g _ e l e m e n tA N DD E V _ B O R N E _ D R O I T E< =@ b d _ e l e m e n t I F@ @ E R R O R< > 0 B E G I N R O L L B A C KT R A N S A C T I O N D E L E T E _ T R E E S E L E C T1 R E T U R N E N D -c a l c u ld el ' i n t e r v a l l ed ed c a l l a g e S E T@ i n t e r v a l l e=@ b d _ e l e m e n t-@ b g _ e l e m e n t+1 -d c a l a g ed e sb o r d sg a u c h e sd e s l m e n t se x t e r n e sa us o u sa r b r e U P D A T ET _ D E V E L O P P E M E N T _ D E V S E T D E V _ B O R N E _ G A U C H E=D E V _ B O R N E _ G A U C H E-@ i n t e r v a l l e W H E R E D E V _ B O R N E _ G A U C H E>@ b g _ e l e m e n t I F@ @ E R R O R< > 0 B E G I N R O L L B A C KT R A N S A C T I O N D E L E T E _ T R E E S E L E C T1 R E T U R N E N D -d c a l a g ed e sb o r d sd r o i t sd e s l m e n t se x t e r n e sa us o u sa r b r e U P D A T ET _ D E V E L O P P E M E N T _ D E V S E T D E V _ B O R N E _ D R O I T E=D E V _ B O R N E _ D R O I T E-@ i n t e r v a l l e W H E R E D E V _ B O R N E _ D R O I T E<@ b g _ e l e m e n t I F@ @ E R R O R< > 0 B E G I N R O L L B A C KT R A N S A C T I O N D E L E T E _ T R E E S E L E C T1 R E T U R N E N D E N D C O M M I TT R A N S A C T I O N D E L E T E _ T R E E

4.7. Les curseurs


Les curseurs sont des mcanismes de mmoire tampons permettant d'accder aux donnes renvoyes par une requte et donc de parcourir les lignes du rsultat.

Un curseur se dfinit dans une instruction DECLARE possdant une requte de type SELECT. Il convient de dfinir pour chaque colonne renvoy une variable de typ Pour lancer la requte associe (et donc placer les donnes dans les buffers appropris) il faut utiliser l'instruction OPEN. Un curseur doit tre referm avec l'instruction CLOSE. Pour librer la mmoire utilise par un curseur, il faut utiliser l'instruction DEALLOCATE. Pour lire les donnes de la ligne courante et les associes aux variables du curseur il faut utiliser l'instruction FETCH.

sqlpro.developpez.com/cours/sqlserver/transactsql/

17/29

Par dfaut l'instruction FETCH navigue en avant d'une ligne chaque lecture dans l'ensemble des donnes du rsultat. Pour naviguer diffremment, on peut qualifier mots clef NEXT, PRIOR, FIRST, LAST, ABSOLUTE n et RELATIVE n, mais il faut avoir dclar le curseur avec l'attribut SCROLL...

Enfin la variable @@fetch_Status permet de savoir si la dernire instruction FETCH passe s'est correctement droule (valeur 0), ce qui permet de tester si l'on e parcours de l'ensemble de donnes. Une boucle traditionnelle de manipulation d'un curseur prend la forme suivante :
-d c l a r a t i o nd e sv a r i a b l e sd ec o l o n n e sp o u rl ec u r s e u r D E C L A R E@ C o l 1T y p e 1 ,@ C o l 2T y p e 2 ,@ C o l 3 ,T y p e 3 . . . -d e c l a r a t i o nd uc u r s e u r D E C L A R EM y C u r s o rC U R S O R F O R S E L E C TC O L 1 ,C O L 2 ,C O L 3 F R O MM y T a b l e -o u v e r t u r ed uc u r s e u r O P E NM y C u r s o r -l e c t u r ed up r e m i e re n r e g i s t r e m e n t F E T C HM y C u r s o rI N T O@ C o l 1 ,@ C o l 2 ,@ C o l 3 . . . -b o u c l ed et r a i t e m e n t W H I L E@ @ f e t c h _ S t a t u s=0 B E G I N t r a i t e m e n t -l e c t u r ed el ' e n r e g i s t r e m e n ts u i v a n t F E T C HM y C u r s o rI N T O@ C o l 1 ,@ C o l 2 ,@ C o l 3 . . . E N D -f e r m e t u r ed uc u r s e u r C L O S Em y C u r s o r -l i b r a t i o nd el am m o i r e D E A L L O C A T Em y C u r s o r

On constate que l'instruction FETCH apparat deux fois. Une premire fois avant la boucle WHILE une seconde fois l'intrieur et en dernire ligne de la boucle WHILE C'est la faon la plus classique et la plus portable d'utiliser des curseurs. NOTA : les performances sont en baisse lorsque l'on utilise tout autre dplacement que le NEXT.

Remarque : il est possible d'effectuer des mises jours de donnes via des curseurs, mais cela n'est pas conseill. Dans ce cas il faut prciser en fin de dclaration UPDATE OF liste_colonne On peut aussi faire du "dirty read" avec les curseurs de SQL Server en prcisant l'attribut INSENSITIVE juste aprs le nom du curseur. La syntaxe complte SQL 2 de la dclaration d'un curseur dans MS SQL Server est :
D E C L A R En o m _ c u r s e u r[ I N S E N S I T I V E ][ S C R O L L ]C U R S O R F O Rr e q u t e _ s e l e c t F O R{ R E A DO N L Y|U P D A T E[ O Fc o l o n n e 1[ ,c o l o n n e 2 . . . ] ] } ]

La syntaxe admise par le Transact SQL de MS SQL Server est plus complte mais moins portable :
D E C L A R En o m _ c u r s e u rC U R S O R[ L O C A L|G L O B A L ]F O R W A R D _ O N L Y|S C R O L L ][ S T A T I C|K E Y S E T|D Y N A M I C|F A S T _ F O R W A R D ]R E A D _ O N L Y| S C R O L L _ L O C K S|O P T I M I S T I C ][ T Y P E _ W A R N I N G ] F O Rr e q u t e _ s e l e c t F O RU P D A T E[ O Fc o l o n n e 1[ ,c o l o n n e 2 . . . ] ] ]

Exemple : voici un petit exercice consistant, pour chaque table de la base en donner le nombre de ligne. Pour cela on utilise une vue d'information de schema pou de toutes les tables et les traiter.
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * / -F r d r i cB R O U A R D-C o m m u n i c a t i cS A-2 0 0 1 1 2 2 4= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -I n f o r m ed un o m b r ed el i g n ed ec h a q u et a b l ed e -l ab a s ed ed o n n e s / * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * / C R E A T EP R O C E D U R ES P _ S Y S _ D B _ D A T A _ R O W S A S -v a r i a b l e sl o c a l e sd el ap r o c d u r e D E C L A R E@ N o m T a b l eV A R C H A R ( 1 2 8 ) , -n o md el at a b l e @ S Q L V A R C H A R ( 1 0 0 0 ) -t e x t ed el ar e q u t ed y n a m i q u e -p a sd em e s s a g e si n t e m p e s t i f s S E TN O C O U N TO N -d c l a r a t i o nd uc u r s e u rp o u ra n a l y s ed e st a b l e sd el ab a s e D E C L A R EC u r s B a s eC U R S O R F O R S E L E C TT A B L E _ N A M E F R O M I N F O R M A T I O N _ S C H E M A . t a b l e s W H E R E T A B L E _ T Y P E=' B A S ET A B L E ' -g e s t i o nd el at a b l ed e sr s u l t a t s:n o md el at a b l et e m p o r a i r e S E T@ N o m T a b l e=' # D A T A _ V O L U M E ' -v i d a g es ie x i s t e n c ed ec e t t et a b l e ,s i n o nc r a t i o n I FE X I S T S ( S E L E C T*F R O M I N F O R M A T I O N _ S C H E M A . t a b l e sW H E R E T A B L E _ N A M E=@ N o m T a b l e ) D E L E T EF R O M# D A T A _ V O L U M E E L S E C R E A T ET A B L E# D A T A _ V O L U M E ( T A B L E _ N A M E V A R C H A R ( 1 2 8 ) , D A T A _ R O W S I N T E G E R ) -o u v e r t u r ed uc u r s e u r

sqlpro.developpez.com/cours/sqlserver/transactsql/

18/29

O P E NC u r s B a s e -l e c t u r ed el ap r e m i r el i g n e F E T C HC u r s B a s eI N T O@ N o m T a b l e -b o u c l el i g n el i g n e W H I L E@ @ F E T C H _ S T A T U S=0 B E G I N -r e q u t ed ' i n s e r t i o na v e cr e c h e r c h ed un o m b r ed el i g n ed el at a b l ea n a l y s e S E T@ S Q L=' I N S E R TI N T O# D A T A _ V O L U M ES E L E C T' ' ' +@ N o m T a b l e+' ' ' ,C O U N T ( * )F R O M'+@ N o m T a b l e E X E C ( @ S Q L ) F E T C HC u r s B a s eI N T O@ N o m T a b l e E N D -f e r m e t u r ee td s a l l o c a t i o nd ' e s p a c em m o i r ed uc u r s e u r C L O S EC u r s B a s e D E A L L O C A T EC u r s B a s e -e n v o id e sd o n n e s S E L E C T*F R O M# D A T A _ V O L U M E -p a sd em e s s a g e si n t e m p e s t i f s S E TN O C O U N TO F F

Exemple : un deuxime exemple plus complexe nous montre comment rechercher l'occurence d'un mot dans toutes les colonnes de toutes les tables de la base. C'est l'exemple vu au paragaphe 4.3 :
/ * \ |r e c h e r c h ed ' u n eo c c u r r e n c ed em o td a n sn ' i m p o r t e | |q u e l l ec o l o n n ed et y p ec a r a c t r e sd en ' i m p o r t e | |q u e l l et a b l ed el ab a s ed ed o n n e s | | -| |F r d r i cB R O U A R D-C O M M U N I C A T I CS A-2 0 0 1 1 2 1 8 | \ -* / C R E A T EP R O C E D U R ES P _ S E A R C H _ S T R I N G _ A N Y F I E L D _ A N Y T A B L E @ S e a r c h W o r dV a r c h a r ( 3 2 ) -m o tr e c h e r c h A S D E C L A R E@ E r r M s gV A R C H A R ( 1 2 8 ) -e f f e td eb o r d1:p a sd em o tp a s s I F@ S e a r c h W o r dI SN U L L B E G I N S E T@ E r r M s g=' I m p o s s i b l ed et r a i t e rc e t t er e c h e r c h ea v e cu na r g u m e n tN U L L ' G O T OL B L _ E R R O R E N D -e f f e td eb o r d2:m o tv i d ep a s s I F@ S e a r c h W o r d=' ' B E G I N S E T@ E r r M s g=' I m p o s s i b l ed et r a i t e rc e t t er e c h e r c h ea v e cu na r g u m e n tv i d e ' G O T OL B L _ E R R O R E N D -e f f e td eb o r d3:m o tc o n t e n a n tu nc a r a c t r ej o k e r%d uL I K E I FC H A R I N D E X ( ' % ' ,@ S e a r c h W o r d )>0 B E G I N S E T@ E r r M s g=' I m p o s s i b l ed et r a i t e rc e t t er e c h e r c h ea v e cu na r g u m e n tc o n t e n a n tu nc a r a c t r e% ' G O T OL B L _ E R R O R E N D -e f f e td eb o r d4:m o tc o n t e n a n tu nc a r a c t r ej o k e r_d uL I K E I FC H A R I N D E X ( ' _ ' ,@ S e a r c h W o r d )>0 B E G I N S E T@ E r r M s g=' I m p o s s i b l ed et r a i t e rc e t t er e c h e r c h ea v e cu na r g u m e n tc o n t e n a n tu nc a r a c t r e_ ' G O T OL B L _ E R R O R E N D -v a r i a b l e sd et r a v a i l D E C L A R E@ T a b l e N a m e V A R C H A R ( 1 2 8 ) ,-n o md el at a b l ep a s s e na r g u m e n t @ C o l u m n L i s t 1V A R C H A R ( 2 0 0 0 ) , -l i s t ed e sc o l o n n e sp o u rc l a u s eS E L E C T @ C o l u m n L i s t 2V A R C H A R ( 2 0 0 0 ) , -l i s t ed e sc o l o n n e sp o u rc l a u s eW H E R E @ S Q L V A R C H A R ( 5 0 0 0 )-r e q u t ed y n a m i q u e -c u r s e u rp a r c o u r a n tt o u t e sl e st a b l e s D E C L A R EC u r T a b l e sC U R S O R F O R S E L E C TD I S T I N C TT A B L E _ N A M E F R O M I N F O R M A T I O N _ S C H E M A . t a b l e s W H E R E T A B L E _ T Y P E=' B A S ET A B L E ' A N D T A B L E _ N A M EI SN O TN U L L -e nc a sd ' e r r e u r I F@ @ E r r o r< >0 B E G I N S E T @ E r r M s g=' E r r e u rd a n sl ar e c h e r c h ed el al s i t ed e st a b l e sc o n c e r n e s ' G O T OL B L _ E R R O R E N D -o u v e r t u r ed uc u s e u r O P E NC u r T a b l e s -l e c t u r ed el ap r e m i r el i g n ed el ' e n s e m b l ed er s u l t a t F E T C HC u r T a b l e sI N T O@ T a b l e N a m e -l al e c t u r ee s t e l l ec o r r e c t e?O u i ,o nb o u c l e! W H I L E@ @ F e t c h _ S t a t u s=0 B E G I N -l e sv a r i a b l e sc o n t e n a n tl e sl i s t e sd e sc o l o n n e ss o n ti n i t i a l i s ev i d e S E T@ C o l u m n L i s t 1=' ' S E T@ C o l u m n L i s t 2=' '

sqlpro.developpez.com/cours/sqlserver/transactsql/

19/29

-c o n s t r u c t i o nd e sl i s t e s S E L E C T@ C o l u m n L i s t 1=@ C o l u m n L i s t 1+C O L U M N _ N A M E + ' ,' , @ C o l u m n L i s t 2=@ C o l u m n L i s t 2+' C O A L E S C E ( ' + C O L U M N _ N A M E + ' ,' ' ' ' )+' F R O M I N F O R M A T I O N _ S C H E M A . C O L U M N S W H E R E T A B L E _ N A M E=@ t a b l e N a m e A N D D A T A _ T Y P EL I K E' % c h a r % ' -p a sd ec o l o n n e sc i b l ep o u rl ar e c h e r c h e ,o nl i tl ' e n r e g i s t r e m e n ts u i v a n te to nb o u c l e I F@ C o l u m n L i s t 1=' ' B E G I N F E T C HC u r T a b l e sI N T O@ T a b l e N a m e C O N T I N U E E N D -s u p p r e s s i o nd ud e r n i e rc a r a c t r ep a r a s i t ed e sl i s t e sd ec o l o n n e S E T@ C o l u m n L i s t 1=S U B S T R I N G ( @ C o l u m n L i s t 1 ,1 ,L E N ( @ C o l u m n L i s t 1 )-1 ) S E T@ C o l u m n L i s t 2=S U B S T R I N G ( @ C o l u m n L i s t 2 ,1 ,L E N ( @ C o l u m n L i s t 2 )-1 ) -c r a t i o nd el ar e q u t ed er e c h e r c h ed el ' e n s e m b l ed e so c c u r e n c e s S E T@ S Q L=' S E L E C T'+ @ C o l u m n L i s t 1 + 'F R O M' + @ T a b l e N a m e + 'W H E R E' + @ C o l u m n L i s t 2 + 'L I K E' ' % ' + @ S e a r c h W o r d + ' % ' ' ' -e x c u t i o nd el ar e q u t ed er e c h e r c h ed e so c c u r e n c e s E X E C ( @ S Q L ) -l e c t u r ed el al i g n es u i v a n t e F E T C HC u r T a b l e sI N T O@ T a b l e N a m e E N D -f e r m e t u r ed uc u r s e u r C L O S EC u r T a b l e s -l i b r a t i o nd el ' e s p a c em m o i r e D E A L L O C A T EC u r T a b l e s P R I N T' * * *R E C H E R C H Ed el ' ' o c c u r e n c e' + @ S e a r c h W o r d +'d a n st o u t el ab a s et e r m i n e* * * ' R E T U R N -g e s t i o nd e se r r e u r s L B L _ E R R O R : R A I S E R R O R( @ E r r M s g ,1 6 ,1 )

Pour mettre jour des donnes dans un curseur, il faut le dclarer avec la clause FOR UPDATE et utiliser un ordre UPDATE portant sur la table vis avec une cl laquelle on rfrence la ligne courante du curseur. Bien entendu la requte situ dans le curseur ne peut porter que sur une seule table ! Exemple :
-d c l a r a t i o nd ' u nc u r s e u rp o u rm i s ej o u r D E C L A R EN o m C u r s e u rC U R S O R F O R S E L E C T. . . F R O ML a T a b l e . . . F O RU P D A T E . . . -e x c u t i o nd el am i s ej o u rs o u sc u r s e u r U P D A T EL a T a b l e S E TC o l o n n e 1=. . . ,C o l o n n e 2=. . . W H E R EC U R R E N TO FN o m C u r s e u r

5. Les triggers

Les triggers ou dclencheurs servent tendre les mcanismes de gestion de l'intgrit rfrentielle (liens d'hritage par exemple) et permettre le contrle de saisie dclench lors de certains vnements de la base de donnes. Un trigger est toujours rattach une table. Les vnements qui dclenche un trigger sont : l'insertion de donnes (INSERT) la suppression de donnes (DELETE) la mise jour (UPDATE)

Ils sont donc dclenchs systmatiquement par une requte SQL, aprs l'excution de cette requte (AFTER), ou la place de l'excution de cette requte (INST n'implmente pas de trigger BEFORE (avant excution), mais nous verrons comment le simuler... En fait le trigger correspond la programmation des vnements des langages d'interfaces graphique, comme Delphi ou Visual Basic.

5.1. Mise en place d'un trigger


On peut dfinir un trigger par l'interface de l'Entreprise Manager comme par un batch cre, par exemple dans l'analyseur de requte.

sqlpro.developpez.com/cours/sqlserver/transactsql/

20/29

Et cliquer sur l'icne appropri "Trigger"

5.2. Syntaxe d'un trigger MS SQL Server 2000


C R E A T ET R I G G E R< n o m _ t r i g g e r > O N< t a b l e _ o u _ v u e > F O R|A F T E R|I N S T E A D O F [I N S E R T][,][U P D A T E][,][ D E L E T E ] A S < c o d e >

Cette syntaxe ne tient pas compte de toutes les possibilits. Emplois typiques : gestion d'hritage avec lien d'exclusion suppression, insertion et mise jour en cascade contrle de validit respect d'intgrit complexes formatage de donnes archivage automatique ...

5.3. Elments du langage spcifique aux triggers


5.3.1. Pseudo tables INSERTED et DELETED

Les pseudo tables INSERTED et DELETED contiennent les donnes respectives de l'insertion ou la mise jour (INSERTED) ou bien de la suppression (DELETED). O dans des requtes comme des tables ordinaires. La structure de ces tables est calque sur le structure de la table sur laquelle repose le trigger.

5.3.2. Fonctions UPDATE et COLUMNS_UPDATED


sqlpro.developpez.com/cours/sqlserver/transactsql/ 21/29

La fonction UPDATE permet de tester si une colonne est vis par un changement de valeur. Elle s'emploie de la manire suivante :
I F[ N O T ]U P D A T E ( < c o l o n n e > ) B E G I N < t r a i t e m e n t > E N D

Elle ne peut tre utilise que dans les triggers de type INSERT et UPDATE.

La fonction COLUMNS_UPDATED() permet d'interroger les colonnes vises par un ordre INSERT ou UPDATE. Elle utilise un masque binaire constitu par le rang ord de la table. Son emploi syntaxique est le suivant :
I F[ N O T ]( C O L U M N S _ U P D A T E D ( )&< m a s q u eo r d i n a l > )< c o m p a r a t e u r >< v a l e u rm a s q u ea t t e n d u e > B E G I N < t r a i t e m e n t > E N D

Un exemple va nous permettre de prciser le fonctionnement de ce mcanisme. Soit une table de prospects comme suit :
C R E A T ET A B L ET _ P R O S P E C T ( P S P _ I D I N T E G E R , P S P _ N O M C H A R ( 3 2 ) , P S P _ P R E N O M V A R C H A R ( 2 5 ) , P S P _ S A I S I E D A T E T I M E , P S P _ T E L V A R C H A R ( 2 0 ) )

Les valeurs ordinales des colonnes de cette table (en fait la position des colonnes lors de la construction de la table) sont les suivantes :
P S P _ I D P S P _ N O M P S P _ P R E N O M P S P _ S A I S I E P S P _ T E L ----1 2 3 4 5

Vous pouvez d'ailleurs retrouver la valeurs de ces positions ordinales par une requte dans les vue de schma normalis, comme suit :

S E L E C TC O L U M N _ N A M E ,O R D I N A L _ P O S I T I O N F R O M I N F O R M A T I O N _ S C H E M A . C O L U M N S W H E R E T A B L E _ N A M E=' T _ P R O S P E C T '

C O L U M N _ N A M E O R D I N A L _ P O S I T I O N P S P _ I D 1 P S P _ N O M 2 P S P _ P R E N O M 3 P S P _ S A I S I E 4 P S P _ T E L 5

Ds lors, si vous voulez savoir si l'ajout ou la mise jour concerne les colonnes PSP_NOM, PSP_PRENOM et PSP_TEL, il faut crire :

I F( C O L U M N S _ U P D A T E D ( )&2 2 )>0 B E G I N < t r a i t e m e n t > E N D I F( C O L U M N S _ U P D A T E D ( )&2 2 )=2 2 B E G I N < t r a i t e m e n t > E N D

pour savoir si au moins l'une des colonnes est concerne

pour savoir si toutes les colonnes sont concernes

Le chiffre 22 s'obtenant par l'addition des puissances de 2 de la position ordinale des colonnes vises, c'est dire :
c o l o n n e :P S P _ I D P S P _ N O M P S P _ P R E N O MP S P _ S A I S I EP S P _ T E L ----o r d i n a l :1 2 3 4 5 p u i s s a n c e2:2 ^ 0=1 2 ^ 1=2 2 ^ 2=4 2 ^ 3=82 ^ 4=1 6 r e t e n u :n o n o u i o u i n o n o u i v a l e u r :0 2 4 0 1 6 =2 2( S O M M Ed e1 6+4+2 )

5.3.3. Annulation des effets d'un trigger

Pour empcher un trigger de produire son effet on peut utiliser le ROLLBACK qui dans ce cas peut porter sur la transaction (ROLLBACK TRANSACTION celle qui a dc par exemple) ou uniquement le trigger (ROLLBACK TRIGGER) c'est dire sur les seuls effets de ce dernier.

C'est par ce biais que l'on peut simuler un trigger BEFORE : utiliser un trigger AFTER et le "rollbacker" ou bien utiliser un trigger INSTEAD et insrer quand mme destination. Attention : un trigger n'est dclench qu'une seule fois, mme si l'ordre SQL qui l'a dclench concerne de nombreuses lignes.

5.4. Exemples de triggers


Premier exemple - contrle de validit de format de donnes. On dsire empcher la saisie de tout numro de tlphone dans la table client qui possde d'autres c chiffres (au maximum 20) et des points de sparation :
C R E A T ET R I G G E RE _ C L I _ I N S O N T _ C L I E N T F O RI N S E R T ,U P D A T E A S -r e q u t ed ec o n t r l ea v e ct a b l ed ' i n s e r t i o n S E L E C TC A S T ( R E P L A C E ( C L I _ T E L ,' . ' ,' ' )a sD E C I M A L ( 2 0 ) ) F R O M I N S E R T E D -r o l l b a c ke nc a sd ' e r r e u r I F@ @ E r r o r< >0 R O L L B A C KT R A N S A C T I O N

sqlpro.developpez.com/cours/sqlserver/transactsql/

22/29

La premire tentative de modification :


U P D A T ET _ C L I E N T S E T C L I _ T E L=' 0 10 20 30 40 5 ' W H E R E C L I _ I D=1 S e r v e u r:M s g8 1 1 4 ,N i v e a u1 6 , t a t5 ,P r o c d u r eE _ C L I _ I N S ,L i g n e6 E r r e u rd ec o n v e r s i o nd ut y p ed ed o n n e sv a r c h a re nn u m e r i c .

provoque une erreur et l'insertion n'a pas lieu. Tandis que la seconde va bien produire ses effets :
U P D A T ET _ C L I E N T S E T C L I _ T E L=' 9 1 . 9 2 . 9 3 . 9 4 . 9 5 ' W H E R E C L I _ I D=1

Le seul inconvnient est que cette faon de procder rejette toutes les lignes insres ou mise jour sans accepter celles qui peuvent tre correctement formates D'autre part on excute cette procdure jusqu'au bout, mme si la colonne CLI_TEL ne subie aucune modification. Nanmoins ce cas peut tre rsolu par un tra utilisant la fonction UPDATE :
C R E A T ET R I G G E RE _ C L I _ I N S O N C L I E N T F O RI N S E R T ,U P D A T E A S -i n u t i l es ip a sd ' u p d a t ed el ac o l o n n ev i s e I FN O TU P D A T E ( C L I _ T E L ) R E T U R N -r e q u t ed ec o n t r l ea v e ct a b l ed ' i n s e r t i o n S E L E C TC A S T ( R E P L A C E ( C L I _ T E L ,' . ' ,' ' )a sD E C I M A L ( 2 0 ) ) F R O M I N S E R T E D -r o l l b a c ke nc a sd ' e r r e u r I F@ @ E r r o r< >0 R O L L B A C KT R A N S A C T I O N

Second exemple - L'exercice consiste maintenant corriger la vole des saisie incorrectes. Tous les caractres de sparation tel que le tiret ou l'espace d'un num devra tre convertis en point.
C R E A T ET R I G G E RE _ C L I _ I N S O N C L I E N T F O RU P D A T E A S -i n u t i l es ip a sd ' u p d a t ed el ac o l o n n ev i s e I FN O TU P D A T E ( C L I _ T E L ) R E T U R N -r e q u t ed ec o r r e c t i o na v e ct a b l ed ' i n s e r t i o n U P D A T Ec l i e n t S E T c l i _ t e l= R E P L A C E ( R E P L A C E ( I . C L I _ T E L ,'' ,' . ' ) ,' ' ,' . ' ) F R O M T _ C L I E N TC I N N E RJ O I NI N S E R T E DI O NC . C L I _ I D=I . C L I _ I D -r o l l b a c ke nc a sd ' e r r e u r I F@ @ E r r o r< >0 R O L L B A C KT R A N S A C T I O N

Ainsi l'ordre :
U P D A T ET _ C L I E N T S E T C L I _ T E L=' 8 87 7 6 65 5 . 4 4 ' W H E R E C L I _ I D=1

donne pour rsultat :


c l i _ i d c l i _ n o m C l i _ t e l --1 D U P O N T 8 8 . 7 7 . 6 6 . 5 5 . 4 4

et la saisie du numro de tlphone a t corrig la vole et se trouve dsormais au format voulu !

Attention : le danger rside dans l'excution rcursive de tels triggers. Comme l'on remet jour la table l'intrieur mme du trigger, celui-ci est nouve phnomne, s'il n'tait pas limit, pourrait provoquer une famine du processus. Il faut donc veiller le limiter. Dans ce sens SQL Server propose deux garde intrinsque au serveur est de ne jamais dpasser 16 niveaux de rcursion. Le second est de proposer une limite plus restrictive l'aide de la procdure sp_configu modifier la variable nested triggers afin d'tendre les limites d'appel de triggers imbriqus. De plus pour connatre le niveau d'imbrication du trigger l'intrieur de ce dernier il suffit de lancer la fonction TRIGGER_NESTLEVEL() qui renvoie une variable de ni Conseil : il est prfrable de ne pas utiliser de triggers imbriqus et donc de laisser le paramtre nested triggers de la configuration 1. Bien entendu ou pourrait tre beaucoup plus fin dans ce genre de contrle et analyser puis remplacer, caractres par caractres. A titre de troisime exemple, nous allons raliser un tel trigger :
C R E A T ET R I G G E RE _ C L I _ I N S O N C L I E N T F O RU P D A T E A S -i n u t i l es ip a sd ' u p d a t ed el ac o l o n n ev i s e I FN O TU P D A T E ( C L I _ T E L ) R E T U R N -o u v e r t u r ed ' u nc u r s e u rs u rl at a b l eI N S E R T E D -p o u rl e st l p h o n e sr e n s e i g n s D E C L A R EC u r I n sC U R S O R F O R S E L E C TC L I _ I D ,C L I _ T E L F R O MI N S E R T E D W H E R EC L I _ T E LI SN O TN U L L I F@ @ e r r o r< >0G O T OL B L _ E R R O R -v a r i a b l ed et r a v a i l D E C L A R E@ I d C l ii n t ,@ T e l A v a n tV A R C H A R ( 2 0 ) ,@ T e l A p r e sV A R C H A R ( 2 0 ) ,

sqlpro.developpez.com/cours/sqlserver/transactsql/

23/29

@ c a rC H A R ( 1 ) ,@ ii n t ,@ ji n t -o u v e r t u r ed uc u r s e u r O P E NC u r I n s I F@ @ e r r o r< >0G O T OL B L _ E R R O R -l e c t u r ep r e m i r el i g n e F E T C HC u r I n sI N T O@ I d C l i ,@ T e l A v a n t -b o u c l ed el e c t u r e W H I L E@ @ F e t c h _ S t a t u s=0 B E G I N -s iv i d er e b o u c l ei m m d i a t e m e n t I F@ T e l A v a n t=' ' B E G I N F E T C HC u r I n sI N T O@ I d C l i ,@ T e l A v a n t C O N T I N U E E N D -s c r u t a t i o nd el av a l e u rd ut l p h o n e S E T@ i=1 S E T@ j=0 S E T@ T e l A p r e s=' ' -b o u c l ed en e t t o y a g es u rt o u sl e sc a r a c t r e s W H I L E@ i< =L E N ( @ T e l A v a n t ) B E G I N -r e p r i s ed uc a r a c t r ed ' o r d r ei S E T@ c a r=S U B S T R I N G ( @ T e l A v a n t , @ i , 1 ) -o nn et r a i t eq u el e sc a r a c t r e sd e09 I F@ c a r=' 0 'o r@ c a r=' 1 'o r@ C a r=' 2 'o r@ C a r=' 3 ' o r@ c a r=' 4 'o r@ c a r=' 5 'o r@ C a r=' 6 'o r@ C a r=' 7 ' o r@ c a r=' 8 'o r@ c a r=' 9 ' B E G I N S E T@ T e l A p r e s=@ T e l A p r e s+@ C a r S E T@ j=@ j+1 E N D S E T@ i= @ i+1 E N D -s iv i d er e b o u c l ei m m d i a t e m e n t I F@ T e l A p r e s=' ' B E G I N F E T C HC u r I n sI N T O@ I d C l i ,@ T e l A v a n t C O N T I N U E E N D -d c o u p a g ep a rt r a n c h ed e2n o m b r e s S E T@ T e l A v a n t=@ T e l A p r e s S E T@ i=1 S E T@ T e l A p r e s=' ' -b o u c l ed ed c o u p a g e W H I L E@ i< =L E N ( @ T e l A v a n t ) B E G I N S E T@ c a r=S U B S T R I N G ( @ T e l A v a n t , @ i , 1 ) S E T@ T e l A p r e s=@ T e l A p r e s+@ C a r I F@ i%2=0 S E T@ T e l A p r e s=@ T e l A p r e s+' ' S E T@ i= @ i+1 E N D -p e t i te f f e td eb o r ds i@ T e l A p r e ss et e r m i n ep a ru nn o m b r ep a i r , -a l o r st i r e te nt r o p! I F@ j%2=0-a up a s a g e%e s tl af o n c t i o nM O D U L Od a n sS Q LS e r v e r S E T@ T e l A p r e s=S U B S T R I N G ( @ T e l A p r e s ,1 ,L E N ( @ T e l A p r e s ) 1 ) -m i s ej o u rs id i f f r e n c e I F@ T e l A v a n t< >@ T e l A p r e s U P D A T EC L I E N T S E T C L I _ T E L=@ T e l A p r e s W H E R E C L I _ I D=@ I d C l i I F@ @ e r r o r< >0G O T OL B L _ E R R O R F E T C HC u r I n sI N T O@ I d C l i ,@ T e l A v a n t E N D -f e r m e t u r ed uc u r s e u re td s a l l o c a t i o nd el ' e s p a c em m o i r e C L O S EC u r I n s D E A L L O C A T EC u r I n s R E T U R N -r o l l b a c ke nc a sd ' e r r e u r L B L _ E R R O R : R O L L B A C KT R A N S A C T I O N

Quatrime exemple - il s'agit maintenant de supprimer en cascade dans diffrentes tables. Si un client (table T_CLIENT) est supprim on doit lui retirer le T_FACTURE) qui le concerne :
C R E A T ET R I G G E RE _ D E L _ C L IO NT _ C L I E N T F O RD E L E T E A S D E L E T EF R O MT _ F A C T U R E F R O MT _ F A C T U R EF I N N E RJ O I ND E L E T E DD O NF . C L I _ I D=D . C L I _ I D I F@ @ E R R O R< >0 R O L L B A C KT R A N S A C T I O N

Bien entendu si vous avez plac de nouveau un trigger permettant de faire de la suppression dans les lignes de facture, alors il sera dclench et supprimera les occ C'est ce que l'on appelle un dclenchement de triggers en cascade.

Cinquime exemple - la gestion d'un lien d'hritage suppose souvent une exclusion mutuelle entre les fils nous allons voir comment grer ce cas de figure. Pa T_VEHICULE dont la spcialisation provoque deux tables : T_AVION et T_BATEAU. Un vhicule peut tre un avion ou bien un bateau mais pas les deux. Une valeu dans T_VEHICULE peut donc se retrouver soit dans T_BATEAU soit dans T_AVION mais on doit viter qu'elle se retrouve dans les deux tables.
C R E A T ET R I G G E RE _ A V I _ I N SO NT _ A V I O N F O RI N S E R T

sqlpro.developpez.com/cours/sqlserver/transactsql/

24/29

A S D E C L A R E@ r o w I n U s ei n t ,@ r o w si n t -o nr e g a r d es il e sc l e f se x i s t e n tb i e nd a n sl at a b l eT _ V E H I C U L E S E L E C T@ R o w I n U s e=C O U N T ( * ) F R O MI N S E R T E D S E L E C T@ R o w s=C O U N T ( * ) F R O MT _ V E H I C U L EV J O I NI N S E R T E DI O NV . V H C _ I D=I . V H C _ I D I F@ R o w I n U s e< >@ R o w s B E G I N R O L L B A C K R A I S E R R O R( ' I d e n t i f i a n td el ' ' h r i t a n ti n e x i s t a n t ' , 1 6 , 1 ) R E T U R N E N D -o nr e g a r d es il e sc l e f sn ' e x i s t e n tp a sd a n sl at a b l eT _ B A T E A U S E L E C T@ R o w s=C O U N T ( * ) F R O MT _ B A T E A UB J O I NI N S E R T E DI O NB . V H C _ I D=I . V H C _ I D I F@ R o w s< >0 B E G I N R O L L B A C K R A I S E R R O R( ' F i l sp r e x i s t a n td a n sl ' ' e n t i t s o e u rB A T E A U ' , 1 6 , 1 ) E N D

Jeu de test :
C R E A T ET A B L ET _ V E H I C U L E ( V H C _ I DI N T ) C R E A T ET A B L ET _ A V I O N ( V H C _ I DI N T , A V I _ M A R Q U EV A R C H A R ( 1 6 ) , A V I _ M O D E L EV A R C H A R ( 1 6 ) ) C R E A T ET A B L ET _ B A T E A U ( V H C _ I DI N T , B T O _ N O MV A R C H A R ( 1 6 ) , B T O _ P O R TV A R C H A R ( 1 6 ) ) I N S E R TI N T OT _ V E H I C U L EV A L U E S( 1 ) I N S E R TI N T OT _ V E H I C U L EV A L U E S( 2 ) I N S E R TI N T OT _ V E H I C U L EV A L U E S( 3 ) I N S E R TI N T OT _ B A T E A UV A L U E S( 2 ,' P e n d u i c k ' ,' L o r i e n t ' ) I N S E R TI N T OT _ B A T E A UV A L U E S( 3 ,' T i t a n i c ' ,' L i v e r p o o l ' ) I N S E R TI N T OT _ A V I O NV A L U E S( 1 ,' B o e i n g ' ,' 7 4 7 ' ) I N S E R TI N T OT _ A V I O NV A L U E S( 3 ,' T u p o l e v ' ,' 1 4 4 ' ) I N S E R TI N T OT _ A V I O NV A L U E S( 5 ,' A i r b u s ' ,' A 3 2 0 ' )

Les deux dernires insertions doivent tre rejetes : l'id 3 existant dans l'entit frre T_BATEAU et l'id 5 n'existant pas dans l'entit mre.

Mais cet exemple est incomplet car il faudrait crer ce mme type de trigger dans la table T_BATEAU pour vrifier la prsence de la clef dans la table pre et v dans la table sur. De mme qu'il serait souhaitable de grer une suppression en cascade pour le pre et ventuellement une modification de la valeur de la clef en vous de jouer...

Sixime exemple - voici maintenant une association d'un genre particulier. L'association 0:0 ! Comment grer une telle relation ? Comme mon habitude un exempl comprhensible : nous voici avec un texte indexer mot pour mot, et pour cela nous devons classer chaque mot rencontr dans le texte dans une table T_ MOT_REF, MOT_PAGE, MOT_LIGNE, MOT_OFFSET) avec la rfrence du texte, la page, la ligne et l'offset en nombre de caractre. Mais il serait absurde d'indexer to pourquoi une table T_MOT_NOIR(MNR_MOT) de mot indsirables (les mots "noirs") est cre, et l'on souhaite qu'aucun des mots index pour le texte ne soit un mo mot noir ne se trouve dans les mots index. C'est donc bien une relation d'exclusion totale, telle que l'intersection des colonnes MOT_MOT de T_MOT et MNR_MOT produise un ensemble vide, ou plus simplement que :
N O TE X I S T S ( S E L E C T* F R O MT _ M O TM O T J O I NT _ M O T _ N O I RM N R O NM O T . M O T _ M O T=M N R . M N R _ M O T )

Soit toujours value vrai ! Un tel trigger n'est pas difficile crire :
C R E A T ET R I G G E RE _ I N S _ M O TO NT _ M O T F O RI N S E R T A S I FE X I S T S ( S E L E C T* F R O MI N S E R T E DI J O I NT _ M O T _ N O I RM O NI . M O T _ M O T=M . M N R _ M O T ) B E G I N R O L L B A C K R A I S E R R O R( ' I n s e r t i o nd ' ' u nm o tn o i ri m p o s s i b l e ' , 1 6 , 1 ) R E T U R N E N D

Il faudrait d'ailleurs penser crire son rciproque dans la table T_MOT_NOIR empchant ainsi l'insertion d'un mot noir pr existant dans la table T_MOT. On peut bien entendu tester un tel trigger avec le jeu d'essai suivant :
C R E A T ET A B L ET _ M O T ( M O T _ M O TC H A R ( 3 2 ) , M O T _ R E FC H A R ( 8 ) , M O T _ P A G EI N T , M O T _ L I G N EI N T , M O T _ O F F S E TI N T )

sqlpro.developpez.com/cours/sqlserver/transactsql/

25/29

C R E A T ET A B L ET _ M O T _ N O I R ( M N R _ M O TC H A R ( 3 2 ) ) I N S E R TI N T OT _ M O T _ N O I RV A L U E S( ' L E ' ) I N S E R TI N T OT _ M O T _ N O I RV A L U E S( ' L A ' ) I N S E R TI N T OT _ M O T _ N O I RV A L U E S( ' L E S ' ) I N S E R TI N T OT _ M O T _ N O I RV A L U E S( ' U N ' ) I N S E R TI N T OT _ M O T _ N O I RV A L U E S( ' U N E ' ) I N S E R TI N T OT _ M O T _ N O I RV A L U E S( ' D E S ' ) I N S E R TI N T OT _ M O T _ N O I RV A L U E S( ' D E ' ) I N S E R TI N T OT _ M O TV A L U E S ( ' L A ' , ' B I B L E ' ,1 4 7 ,2 3 ,1 4 ) I N S E R TI N T OT _ M O TV A L U E S ( ' V A L L E ' ,' B I B L E ' ,1 4 7 ,2 3 ,1 4 ) I N S E R TI N T OT _ M O TV A L U E S ( ' D E ' , ' B I B L E ' ,1 4 7 ,2 3 ,1 4 ) I N S E R TI N T OT _ M O TV A L U E S ( ' L A ' , ' B I B L E ' ,1 4 7 ,2 3 ,1 4 ) I N S E R TI N T OT _ M O TV A L U E S ( ' M O R T ' , ' B I B L E ' ,1 4 7 ,2 3 ,1 4 )

En conclusion nous pouvons dire que les triggers de la version 7 de SQL Server sont assez limits en ne permettent pas de grer trs finement les donnes. Ils ne f mcanisme pratique et simple lorsque l'on veut par exemple manipuler ligne ligne et colonne par colonne la vailidit des donnes et les rectifier la vole avant l'in Il semble que la version 2000 de SQL Server respecte plus la norme SQL 2 sur ce point. Septime exemple - dans une relation d'hritage, comment insrer dans une table fille alors que l'insertion dans la table mre est un pr requis ? Par exemple, nous avons une table des personnes, une table des clients et une table des employs. Ces tables sont construites de la sorte :

C R E A T ET A B L ET _ P E R S O N N E _ P R S ( P R S _ I D I N TI D E N T I T YN O TN U L LP R I M A R YK E Y , P R S _ N O M C H A R ( 3 2 )N O TN U L L , P R S _ P R E N O M V A R C H A R ( 1 6 ) ) C R E A T ET A B L ET _ E M P L O Y E _ E M P ( P R S _ I D I N TN O TN U L LP R I M A R YK E Y R E F E R E N C E ST _ P E R S O N N E _ P R S( P R S _ I D ) , E M P _ M A T R I C U L EV A R C H A R ( 8 ) )

On ne peut donc pas insrer directement dans T_EMPLOYE_EMP, sauf utiliser une vue et un trigger INSTEAD OF... Creation de la vue V_EMPLOYEE_EMP :
C R E A T EV I E WV _ E M P L O Y E E _ E M P A S S E L E C TP . P R S _ I D ,P . P R S _ N O M ,P . P R S _ P R E N O M ,E . E M P _ M A T R I C U L E F R O M T _ P E R S O N N E _ P R SP I N N E RJ O I NT _ E M P L O Y E _ E M PE O NP . P R S _ I D=E . P R S _ I D

Ds lors on peut crer un trigger d'insertion dans cette vue qui va dcomposer les lments insrer et injecter les donnes dans les deux tables :
C R E A T ET R I G G E RT R G _ I N S _ E M P L O Y E O NV _ E M P L O Y E E _ E M P I N S T E A DO FI N S E R T A S B E G I N I N S E R TI N T OT _ P E R S O N N E _ P R S( P R S _ N O M ,P R S _ P R E N O M ) S E L E C TP R S _ N O M ,P R S _ P R E N O M F R O M I N S E R T E D I N S E R TI N T OT _ E M P L O Y E _ E M P( P R S _ I D ,E M P _ M A T R I C U L E ) S E L E C T@ @ I D E N T I T Y ,E M P _ M A T R I C U L E F R O M I N S E R T E D E N D

Utilisation :

I N S E R TI N T OV _ E M P L O Y E E _ E M PV A L U E S( 1 ,' D U P O N T ' ,' M a u r i c e ' ,' X F 5 0 9 0 A Z ' ) S E L E C T*F R O MT _ P E R S O N N E _ P R S P R S _ I D P R S _ N O M P R S _ P R E N O M --1 D U P O N T M a u r i c e S E L E C T*F R O MT _ E M P L O Y E _ E M P P R S _ I D E M P _ M A T R I C U L E -1 X F 5 0 9 0 A Z

NOTA : voici le trigger de contrle d'intgrit des bornes des arborescence exprimes sous forme intervallaire (voir l'article sur ce sujet) :
C R E A T ET R I G G E RE _ D E V _ U N I Q U E _ B O R N EO NT _ D E V E L O P P E M E N T _ D E V F O RI N S E R T ,U P D A T E ,D E L E T E A S -v r i f i c a t i o nd el ' u n i c i t d el ' e n s e m b l ed e sb o r n e s( b o r n e sg a u c h e se tb o r n e sd r o i t e ) I FE X I S T S( S E L E C TC O U N T ( * ) ,B O R N E F R O M ( S E L E C TD E V _ B O R N E _ D R O I T EA SB O R N E F R O M T _ D E V E L O P P E M E N T _ D E V U N I O NA L L S E L E C TD E V _ B O R N E _ G A U C H E A SB O R N E F R O M T _ D E V E L O P P E M E N T _ D E V )T G R O U PB YB O R N E H A V I N GC O U N T ( * )< >1 ) R O L L B A C K -v r i f i c a t i o nd el ab o r n em a x i m a l ec o m m e t a n td e u xf o i sl en o m b r ed el i g n e sd el at a b l e I F( S E L E C TM A X ( B O R N E )

sqlpro.developpez.com/cours/sqlserver/transactsql/

26/29

F R O M

( S E L E C TD E V _ B O R N E _ D R O I T EA SB O R N E F R O M T _ D E V E L O P P E M E N T _ D E V U N I O NA L L S E L E C TD E V _ B O R N E _ G A U C H E A SB O R N E F R O M T _ D E V E L O P P E M E N T _ D E V )T )< >( S E L E C TC O U N T ( * )*2 F R O M T _ D E V E L O P P E M E N T _ D E V )

B E G I N R O L L B A C K R A I S E R R O R( ' U n eb o r n ed p a s s el av a l e u rm a x i m a l ea t t e n d u e ' ,1 6 ,1 ) E N D -v r i f i c a t i o nd el ab o r n em i n i m a l ec o m m e t a n t g a l eu n I F( S E L E C TM I N ( B O R N E ) F R O M ( S E L E C TD E V _ B O R N E _ D R O I T EA SB O R N E F R O M T _ D E V E L O P P E M E N T _ D E V U N I O NA L L S E L E C TD E V _ B O R N E _ G A U C H E A SB O R N E F R O M T _ D E V E L O P P E M E N T _ D E V )T )< >1 B E G I N R O L L B A C K R A I S E R R O R( ' U n eb o r n ed p a s s el av a l e u rm i n i m a l ea t t e n d u e ' ,1 6 ,1 ) E N D

6. Cryptage du code, liaison au schema et recompilation

ENCRYPTION indique que SQL Server crypte l'entre de la table systme contenant le texte de l'instruction (procdure, fonction, trigger ou vue). L'utilisation de cet le confidentialit du code et vite la publication de la procdure dans le cadre de la rplication.

C'est un moyen qui ne garantie pas qu'un utilisateur mal intentionn n'insre des donnes impropres. Mais cette technique permet de contraindre l'excution de cert seuls possesseurs d'un algorithme de vrification. Pour comprendre comment mettre en oeuvre un tel mcanisme, voici un exemple complet :

-u n et a b l ed o n to nn ed s i r ep a sq u en ' i m p o r t eq u ii n s r ed e d a n s C R E A T ET A B L ET _ C R Y P T E E _ C R P ( C R P _ I D I N TN O TN U L LP R I M A R YK E Y , C R P _ N O M C H A R ( 3 2 )N O TN U L L , C R P _ C O N T R O LV A R B I N A R Y ( 8 ) ) -u nt r i g g e rq u iv r i f i el ac o n c o r d a n c ee n t r el en o me tl ec o d ed ec o n t r o l e C R E A T ET R I G G E RT R G _ C R P _ I N S _ U P D O NT _ C R Y P T E E _ C R P W I T HE N C R Y P T I O N F O RI N S E R T ,U P D A T E A S I FN O TE X I S T S ( S E L E C T* F R O MI N S E R T E D W H E R EC R P _ C O N T R O L=C A S T ( S U B S T R I N G ( C R P _ N O M ,1 ,8 )A SV A R B I N A R Y ( 8 ) ) ) R O L L B A C K -t e n t a t i v ed ' i n s e r t i o ns a n sc o n n a i s s a n c ed el ' a l g o r i t m ed ec o n t r o l e I N S E R TI N T OT _ C R Y P T E E _ C R PV A L U E S( 1 ,' D u p o n t ' ,C A S T ( ' 'A SV A R B I N A R Y ( 8 ) ) )

S E L E C T*F R O MT _ C R Y P T E E _ C R P C R P _ I D C R P _ N O M C R P _ C O N T R O L ---a u c u nr s u l t a tl ' i n s e r t i o na t r o o l b a c k p a rl et r i g g e r! -t e n t a t i v ed ' i n s e r t i o na v e cl ec o d ed ec o n t r o l e I N S E R TI N T OT _ C R Y P T E E _ C R PV A L U E S( 1 ,' D u p o n t ' ,C A S T ( ' D u p o n t 'A SV A R B I N A R Y ( 8 ) ) ) S E L E C T*F R O MT _ C R Y P T E E _ C R P C R P _ I D C R P _ N O M C R P _ C O N T R O L --1 D u p o n t 0 x 4 4 7 5 7 0 6 F 6 E 7 4 2 0 2 0 -l ' i n s e r t i o nab i e ne tl i e u!

Voila comment certains diteurs de progiciel se protgent des petits malins qui tente de "pourrir" leur base en y insrant des donnes sans passer par l'application !

RECOMPILE indique que SQL Server n'utilise pas le cache pour le plan de la procdure (ou de la vue). Elle sera donc recompile chaque l'excution. Cela est con utilisez des valeurs temporaires ou atypiques (alatoires par exemple).

SCHEMABINDING Indique qu'une fonction (vue ou index) est lie aux objets base de donnes auxquels elle fait rfrence. La fonction ainsi cre ne pourra tre sup les objets base de donnes auxquels la fonction fait rfrence sont supprims pralablement.

7. ANNEXE BIBLIOGRAPHIQUE
Livres : Transact SQL Programming - Kelvin Kline, Lee Gould & Andrew Zanevsky - O'Reilly Professionnal SQL Server 7 Programming - Robert Vieira - Wrox Inside Microsoft SQL Server 7.0 - Ron Soukup, Kalen Delaney, Microsoft Press SQL Server 7 - Marc Israel - Eyrolles SQL Server 7.0 - Stephen Wynkoop - Campus Press SQL Server DBA - Mark Spenik, Orryn Sledge - Campus Press SQL Server 2000 - Marc Israel - Eyrolles

sqlpro.developpez.com/cours/sqlserver/transactsql/

27/29

SQL Server au quotidien Expert - M. F. Garcia, J Reding, E. Whalen, A. Deluca - Microsoft Press Sites web : http://www.microsoft.com http://www.developpez.com/ http://www.multimania.com/lewisdj/sql.htm http://www.sqlservercentral.com/ http://www.sqlteam.com/

Livres SQL - dveloppement SQL - le cours de rfrence sur le langage SQL Avant d'aborder le SQL Dfinitions SGBDR fichier ou client/serveur ? La base de donnes exemple (gestion d'un htel) Modlisation MERISE Mots rservs du SQL Le SQL de A Z Les fondements Le simple (?) SELECT Les jointures, ou comment interroger plusieurs tables Groupages, ensembles et sous-ensembles Les sous-requtes Insrer, modifier, supprimer Cration des bases Grer les privilges ("droits") Toutes les fonctions de SQL Les techniques des SGBDR Les erreur les plus frquentes en SQL Les petits papiers de SQLPro Confrence Borland 2003 L'hritage des donnes Donnes et normes Modlisation par mta donnes Optimisez votre SGBDR et vos requtes SQL Le temps, sa mesure, ses calculs QBE, le langage de ZLOOF Des images dans ma base La jointure manquante Clefs auto incrmentes L'indexation textuelle L'art des "Soundex" Une seule colonne, plusieurs donnes La division relationnelle, mythe ou ralit ? Gestion d'arborescence en SQL L'avenir de SQL Mthodes et standards Les doublons SQL Server Eviter les curseurs Un aperu de TRANSACT SQL V 2000 SQL Server 2000 et les collations Scurisation des accs aux bases de donnes SQL Server Des UDF pour SQL Server SQL Server et le fichier de log... Paradox De vieux articles publis entre 1995 et 1999 dans la dfunte revue Point DBF

sqlpro.developpez.com/cours/sqlserver/transactsql/

28/29

C opyright 2 0 0 4 Frdric Brouard. A uc une reproduc tion, mme partielle, ne peut tre faite de c e s ite et de l'ens emble de s on c ontenu : textes , doc uments , images , etc . s ans l'autoris ation expres s e de l'auteur. Sinon vous enc ourez s elon la loi jus qu' trois ans de pris on et jus qu' 3 0 0 0 0 0 de dommages et intrts . C ette page es t dpos e.

Responsable bnvole de la rubrique SGBD & SQL : le Rdacteur en Chef - Contacter par email

Developpez.com
Nous contacter Participez Informations lgales

Services
Forum SGBD & SQL Blogs Hbergement Copyright 2000-2013 - www.developpez.com

Partenaires
Hbergement Web

sqlpro.developpez.com/cours/sqlserver/transactsql/

29/29

Das könnte Ihnen auch gefallen