SQL Server - La FAQConsultez toutes les FAQ

Nombre d'auteurs : 13, nombre de questions : 119, dernière mise à jour : 31 mai 2011  Ajouter une question

 

Question / réponses à tout ce que vous avez toujours voulu savoir sur Microsoft SQL Server sans jamais oser le demander


SommaireTrucs et Astuces en T-SQLLimiter le jeu de résultat (14)
précédent sommaire suivant
 

Pour limiter le nombre de ligne retourné par une commande Select, MS SQL Serveur fournit la commende TOP, C'est un équivalent de la commande Limit de MySQL
Exemple:

Code tsql : Sélectionner tout
1
2
3
--Retouner 100 lignes d'une table T_Client 
SELECT TOP 100 * 
FROM t_client
OU

Code tsql : Sélectionner tout
1
2
3
4
5
6
SET ROWCOUNT 100 
GO 
SELECT * FROM t_client 
GO 
SET ROWCOUNT 0 
GO

Mis à jour le 28 septembre 2005 Fabien Celaia WOLO Laurent

Le SGBD MySQL fournit une fonctionalité intéressante dans les SELECT : LIMIT.

Code sql : Sélectionner tout
SELECT * FROM MATABLE LIMIT 10, 30
Affiche 30 lignes à partir de l'enregistrement 10. Voici une solution pour implémenter cette fonctionalité en T-SQL :

Code tsql : Sélectionner tout
1
2
3
4
5
6
7
SELECT * FROM (  
         SELECT TOP 30 Field1, Field2 FROM (  
         SELECT TOP 10 Field1, Field2  
         FROM  matable  
        ORDER BY monchamp asc  
        ) AS tbl1 ORDER BY monchamp desc  
        ) AS tbl2 ORDER BY monchamp asc
et une petite fonction php pour généraliser, a améliorer selon vos besoins :

Code tsql : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function getLimitMSSQL($start, $nbrows, $fields, $table, $where, $orderfield, $sort = 'asc') {  
$top = $start + $nbrows ;  
if ( $sort == 'asc' ) {  
   $asc = 'asc' ;  
   $desc = 'desc' ;  
} else {  
   $asc = 'desc' ;  
   $desc = 'asc' ;  
}  
$sql = '' ;  
   $sql = "SELECT * FROM (  
                           SELECT TOP $nbrows $fields from (  
                               SELECT TOP $top $fields  
                               FROM $table  
                               $where  
                               ORDER BY $orderfield $asc  
                           ) tbl1 ORDER BY $orderfield $desc  
           ) as tbl2 order by $orderfield $asc  
       " ;  
return $sql ;  
}

Mis à jour le 28 septembre 2005 WOLO Laurent

En interrogeant la variable globale @@rowcount, directement après l'appel de la requête

Mis à jour le 28 septembre 2005 Fabien Celaia

Code tsql : Sélectionner tout
set rowcount n

Mis à jour le 28 septembre 2005 Fabien Celaia

Code tsql : Sélectionner tout
Set rowcount 0

Mis à jour le 28 septembre 2005 Fabien Celaia

Si la requête dynamique ne retourne qu'une seule valeur

Code tsql : Sélectionner tout
1
2
3
4
CREATE PROCEDURE RecupVariable AS 
DECLARE @VAR AS VARCHAR(10) 
SET @VAR = (SELECT champ FROM Table WHERE ..)  
PRINT @VAR
Si elle retourne plusieurs valeurs ou plusieurs lignes, passer par une table de travail

Code tsql : Sélectionner tout
1
2
3
4
5
6
7
8
CREATE PROCEDURE RecupVariable @PARAM INT 
AS 
DECLARE @VAR AS VARCHAR(10),  @QUERY AS VARCHAR(150) 
SET @QUERY = 'SELECT champ1 INTO TableTempo FROM Table WHERE champ2 = ' + CAST(@PARAM AS VARCHAR(5)) 
EXEC(@QUERY)  
SET @VAR = (SELECT Champ1 FROM TableTempo) 
DROP TABLE TableTempo 
PRINT @VAR

Mis à jour le 28 avril 2006 HULK

deux solutions :

  • un grand varchar avec un délimiteur, que l'on parse dans une procédure stockée, par exemple à l'aide d'une fonction qui retourne une table.
  • une structure XML que l'on envoie dans un grand varchar, ou un TEXT, et que l'on convertit en table dans une procédure stockée avec OPENXML.

Pour un XML du genre:

Code xml : Sélectionner tout
1
2
3
4
5
6
<Elements> 
  <Element> 
      <Key/> 
      <Value/> 
  </Element> 
 </Elements>
Coder comme ceci

Code tsql : Sélectionner tout
1
2
3
4
5
6
7
8
DECLARE @idoc int 
DECLARE @tField TABLE (FieldName varchar(100), Value varchar(100)) 
 
EXEC master.dbo.sp_xml_preparedocument @idoc OUTPUT, @KeyValue 
 
INSERT INTO @tField (FieldName, Value) 
SELECT FieldName, Value 
FROM OPENXML(@idoc, '/Elements/Element', 2) WITH (FieldName varchar(100) 'Key', Value varchar(100))
.. ou sans passer par une variable table, directement dans un JOIN.

En étant conscient que les performances du OPENXML peuvent poser problème sur un serveur très sollicité. A tester.

Mis à jour le 28 août 2006 rudib

Voici le code pour réaliser ceci

Code tsql : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
-- Le fichier binaire 
  DECLARE @s varbinary(2048) 
  SET @s = 0x47494...code hexa du fichier 
  
  DECLARE @o int 
  DECLARE @r int 
  EXEC sp_oacreate 'adodb.stream', @o output 
  EXEC sp_oasetproperty @o, 'type', 2 
  EXEC sp_oamethod @o, 'open' 
  EXEC sp_oamethod @o, 'writetext', NULL, @s 
  
  EXEC sp_oacreate 'adodb.stream', @r output 
  EXEC sp_oasetproperty @r, 'type', 1 
  EXEC sp_oamethod @r, 'open' 
  EXEC sp_oasetproperty @o, 'position', 2 
  EXEC sp_oamethod @o, 'copyto', NULL, @r 
  EXEC sp_oamethod @r, 'savetofile', NULL, @basedir, 2
On peut utiliser la primitive READTEXT pour obtenir le code hexa d'une colonne image, par exemple.

Mis à jour le 7 juillet 2007 davidou2001

SQL Server n'est pas compatible avec la norme SQL sur la jointure externe avec *=. Il ne donne pas les mêmes résultats...

Code tsql : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
CREATE TABLE T1 (C1 INT) 
  
INSERT INTO T1 VALUES (1) 
INSERT INTO T1 VALUES (0) 
INSERT INTO T1 VALUES (1) 
  
CREATE TABLE T2 (C2 INT) 
  
INSERT INTO T2 VALUES (2) 
INSERT INTO T2 VALUES (0) 
INSERT INTO T2 VALUES (2) 
  
CREATE TABLE T3 (C3 INT) 
  
INSERT INTO T3 VALUES (3) 
INSERT INTO T3 VALUES (0) 
INSERT INTO T3 VALUES (3) 
  
  
SELECT * 
FROM   T1 
       LEFT OUTER JOIN T2 ON T1.C1 = T2.C2 
       LEFT OUTER JOIN T3 ON T1.C1 = T3.C3 
  
C1          C2          C3           
----------- ----------- -----------  
1           NULL        NULL 
0           0           0 
1           NULL        NULL 
  
SELECT * 
FROM   T1, T2, T3 
WHERE  C1 *= C2 AND C1 *= C3 
  
C1          C2          C3           
----------- ----------- -----------  
1           NULL        NULL 
0           0           0 
1           NULL        NULL 
  
-- exact ! 
  
SELECT * 
FROM   T1 
       LEFT OUTER JOIN T2 ON T1.C1 = T2.C2 
       LEFT OUTER JOIN T3 ON T2.C2 = T3.C3 
  
C1          C2          C3           
----------- ----------- -----------  
1           NULL        NULL 
0           0           0 
1           NULL        NULL 
  
SELECT * 
FROM   T1, T2, T3 
WHERE  C1 *= C2  
  AND  C2 *= C3 
  
-- Serveur : Msg 301, Niveau 16, État 1, Ligne 1 
-- La requête comporte une requête de jointure externe qui n'est pas autorisée. 
-- SQL Server ne sait pas faire des jointures externes en cascade... 
  
  
SELECT * 
FROM   T1 
       INNER JOIN (SELECT * 
                        FROM   T2) AS T 
            ON T1.C1 = T.C2 
       RIGHT OUTER JOIN T3 ON T.C2 = T3.C3 
  
C1          C2          C3           
----------- ----------- -----------  
NULL        NULL        3 
0           0           0 
NULL        NULL        3 
  
SELECT * 
FROM   T1, (SELECT * FROM   T2) AS T, T3 
WHERE  C1 = C2  
  AND  C2 =* C3 
  
-- Serveur : Msg 303, Niveau 16, État 1, Ligne 1 
-- La table 'T2' est un membre interne d'une clause de jointure externe. Cela n'est pas autorisé si la table participe aussi à une clause JOIN régulière. 
-- SQL Server ne sait pas faire des jointures externes en cascade... 
  
  
SELECT * 
FROM   T1 
       RIGHT OUTER JOIN T2 ON T1.C1 = T2.C2 
       RIGHT OUTER JOIN T3 ON T1.C1 = T3.C3 
  
C1          C2          C3           
----------- ----------- -----------  
NULL        NULL        3 
0           0           0 
NULL        NULL        3 
  
SELECT * 
FROM   T1, T2, T3 
WHERE  C1 =* C2 
  AND  C1 =* C3 
  
C1          C2          C3           
----------- ----------- -----------  
NULL        2           3 
NULL        2           0 
NULL        2           3 
NULL        0           3 
0           0           0 
NULL        0           3 
NULL        2           3 
NULL        2           0 
NULL        2           3 
  
-- résultat totalement faux !!!
N'oubliez pas que avant que la norme SQL ne statut en 1992 sur les jointures externes chaque éditeur de SGBD était llibre de faire à sa sauce... Cette interprétation de la jointure externe date de l'époque Sybase...

Depuis 2005 une telle syntaxe est heureusement interdite !

Mis à jour le 23 février 2008 SQLpro

Dans cet article sur les arbres intervallaires, je n'ai pas mentionné comment déplacer un sous arbre modélisé par intervalle. Voici comment procéder...

Cette procédure exemple (sous forme de primitive) permet de déplacer un sous arbre en le faisant devenir un fils ainé ou cadet, un grand frère ou un petit frère et même un père par rapport à l'élément ciblé.

Code sql : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
/******************************************************************************  
-- création d'une procédure de déplacement d'un sous arbre                 
******************************************************************************/  
CREATE PROCEDURE dbo.P_MOVE_TRE @id int,         -- Ident de l'élément déplacé  
                              @id_parent int,  -- Ancêtre de destination  
                              @mode char(2),   -- FG : Grand Frère, PF : Petit Frère, FA : Fils ainé, FC : Fils cadet, P : Père, etc  
                              @recurs bit      -- La descendance est déplacé aussi  
AS  
/******************************************************************************  
* PROCÉDURE DÉPLACEMENT D'UN SOUS ARBRE DANS UN ARBRE MODÉLISÉ PAR INTERVALLE *  
*******************************************************************************  
* Frédéric Brouard   -   SQLPro   -   http://www.sqlspot.com   -   2004-06-10 *  
*******************************************************************************  
* PARAMÈTRES :                                                                *  
*    @id           clef de l'élément à déplacer (racine du sous arbre)        *  
*    @id_parent    parent du point de déplacement (ancrage)                   *  
*    @mode         parentèle au point d'ancrage. Valeurs possibles :          *  
*                  GF : Frère (grand)                                         *  
*                  PF : Frère (petit)                                         *  
*                  FA : Fils ainé                                             *  
*                  FC : Fils cadet                                            *  
*                  P  : Père                                                  *  
*    @recurs       si 1 déplacement de tout le sous arbre,                    *  
*                  si 0 déplacement de l'élément seul                         *  
******************************************************************************/  
  
DECLARE @OK     int,  
        @bdmax  int, -- limite supérieure droite de l'arborescence  
        @deltab int, -- Delta de borne  
        @bgd    int, -- Infos sur le déplacé  
        @bdd    int,  
        @nivd   int,  
        @bgp    int,    -- Infos sur le parent  
        @bdp    int,  
        @nivp   int  
  
-- Mode silencieux  
SET NOCOUNT ON;  
  
-- contrôle d'exécution  
IF @mode IS NULL  
BEGIN  
   RAISERROR ('Déplacement impossible sans mode ! (TABLE dbo.T_NOMENCLATURE_PIECES_NMC)', 16, 1)  
   RETURN  
END  
  
IF @recurs IS NULL  
BEGIN  
   RAISERROR ('Déplacement impossible sans type ! (TABLE dbo.T_NOMENCLATURE_PIECES_NMC)', 16, 1)  
   RETURN  
END  
  
IF @id IS NULL  
BEGIN  
   RAISERROR ('Déplacement impossible sans précision de l''élément ! (TABLE dbo.T_NOMENCLATURE_PIECES_NMC)', 16, 1)  
   RETURN  
END  
  
IF @id_parent IS NULL  
BEGIN  
   RAISERROR ('Déplacement impossible sans précision du destinataire ! (TABLE dbo.T_NOMENCLATURE_PIECES_NMC)', 16, 1)  
   RETURN  
END  
  
IF @id = @id_parent  
BEGIN  
   RAISERROR ('Déplacement impossible , origine et destination identique ! (TABLE dbo.T_NOMENCLATURE_PIECES_NMC)', 16, 1)  
   RETURN  
END  
  
SET @mode = UPPER(@mode)  
IF NOT( @mode = 'GF' OR @mode = 'PF' OR @mode = 'FC' OR @mode = 'FA' ) --  OR @mode = 'P' -- PBT: à vérifier !  
BEGIN  
   RAISERROR ('Déplacement impossible, mode inconnu ! (TABLE dbo.T_NOMENCLATURE_PIECES_NMC)', 16, 1)  
   RETURN  
END  
  
  
-- démarrage transaction -------------------  
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE   
BEGIN TRANSACTION MOVE_NMC  
  
-- L'élément existe toujours ?  
SELECT @OK = count(*) FROM dbo.T_NOMENCLATURE_PIECES_NMC WHERE NMC_ID = @id  
IF @OK IS NULL OR @OK = 0  
BEGIN  
   RAISERROR ('Déplacement impossible, l''élément n''existe pas ! (TABLE dbo.T_NOMENCLATURE_PIECES_NMC)', 16, 1)  
   GOTO LBL_ERROR  
   RETURN  
END  
  
-- Le parent existe toujours ?  
SELECT @OK = count(*) FROM dbo.T_NOMENCLATURE_PIECES_NMC WHERE NMC_ID = @id_parent  
IF @OK IS NULL OR @OK = 0  
BEGIN  
   RAISERROR ('Déplacement impossible, le parent n''existe pas ! (TABLE dbo.T_NOMENCLATURE_PIECES_NMC)', 16, 1)  
   GOTO LBL_ERROR  
   RETURN  
END  
  
-- On récupère la borne supérieure max de l'ensemble  
SELECT @bdmax = max(NMC_BD) FROM dbo.T_NOMENCLATURE_PIECES_NMC  
IF @bdmax IS NULL OR @bdmax = 0  
BEGIN  
   RAISERROR ('Déplacement impossible, la borne BD est nulle ! (TABLE dbo.T_NOMENCLATURE_PIECES_NMC)', 16, 1)  
   GOTO LBL_ERROR  
   RETURN  
END  
  
-- On a un élément : on récupère ses caractéristiques  
SELECT @bgd = NMC_BG, @bdd = NMC_BD, @nivd = NMC_NIVEAU   
       FROM dbo.T_NOMENCLATURE_PIECES_NMC   
       WHERE NMC_ID = @id  
IF @@ERROR <> 0  
BEGIN  
   GOTO LBL_ERROR  
   RETURN  
END  
  
SET @deltab = @bdmax + 1 - @bgd  
  
-- DEBUT de l'opération proprement dite...  
  
-- Opération récursive ?  
IF @recurs = 0  
BEGIN  
   -- Seul l'élément doit être déplacé  
  
   -- déplacement de l'élément seul en fin de liste  
   UPDATE dbo.T_NOMENCLATURE_PIECES_NMC  
          SET NMC_BG = NMC_BG + @deltab,  
              NMC_BD = NMC_BD + @deltab  
          WHERE NMC_ID = @id  
   IF @@ERROR <> 0  
   BEGIN  
      GOTO LBL_ERROR  
      RETURN  
   END  
  
   -- remontée de ses descendants dans la hiérarchie  
   UPDATE dbo.T_NOMENCLATURE_PIECES_NMC  
          SET NMC_BG = NMC_BG - 1,  
              NMC_BD = NMC_BD - 1,  
              NMC_NIVEAU = NMC_NIVEAU - 1  
          WHERE NMC_BG > @bgd AND NMC_BD < @bdd  
   IF @@ERROR <> 0  
   BEGIN  
      GOTO LBL_ERROR  
      RETURN  
   END  
   -- rééquilibrage de l'arbre  
   UPDATE dbo.T_NOMENCLATURE_PIECES_NMC  
          SET NMC_BG = NMC_BG - 2  
          WHERE NMC_BG > @bdd AND NMC_BG < @bdmax  
   IF @@ERROR <> 0  
   BEGIN  
      GOTO LBL_ERROR  
      RETURN  
   END  
   --      
   UPDATE dbo.T_NOMENCLATURE_PIECES_NMC  
          SET NMC_BD = NMC_BD - 2  
          WHERE NMC_BD > @bdd AND NMC_BD <= @bdmax  
   IF @@ERROR <> 0  
   BEGIN  
      GOTO LBL_ERROR  
      RETURN  
   END  
  
   -- Mise en place de l'élement deplacé  
  
   -- On récupère d'abord les caractéristiques du parent  
   SELECT @bgp = NMC_BG, @bdp = NMC_BD, @nivp = NMC_NIVEAU   
          FROM dbo.T_NOMENCLATURE_PIECES_NMC   
          WHERE NMC_ID = @id_parent  
   IF @@ERROR <> 0  
   BEGIN  
      GOTO LBL_ERROR  
      RETURN  
   END  
  
   -- Grand frère  
   IF @mode = 'GF'  
   BEGIN  
      -- Limite sup.  
      UPDATE dbo.T_NOMENCLATURE_PIECES_NMC  
             SET NMC_BD = NMC_BD + 2  
             WHERE NMC_BD >= @bdp AND NMC_BD <= @bdmax  
      IF @@ERROR <> 0  
      BEGIN  
         GOTO LBL_ERROR  
         RETURN  
      END  
  
      -- Limite inf.  
      UPDATE dbo.T_NOMENCLATURE_PIECES_NMC  
             SET NMC_BG = NMC_BG + 2  
             WHERE NMC_BG >= @bgp AND NMC_BG < @bdmax  
      IF @@ERROR <> 0  
      BEGIN  
         GOTO LBL_ERROR  
         RETURN  
      END  
  
      UPDATE dbo.T_NOMENCLATURE_PIECES_NMC  
             SET NMC_BG = @bgp,  
                 NMC_BD = @bgp + 1,  
                 NMC_NIVEAU = @nivp  
             WHERE NMC_ID = @id  
      IF @@ERROR <> 0  
      BEGIN  
         GOTO LBL_ERROR  
         RETURN  
      END  
   END  
  
   -- Petit Frère   
   IF @mode = 'PF'  
   BEGIN  
      -- Limite sup.  
      UPDATE dbo.T_NOMENCLATURE_PIECES_NMC  
             SET NMC_BD = NMC_BD + 2  
             WHERE NMC_BD > @bdp AND NMC_BD <= @bdmax  
      IF @@ERROR <> 0  
      BEGIN  
         GOTO LBL_ERROR  
         RETURN  
      END  
  
      -- Limite inf.  
      UPDATE dbo.T_NOMENCLATURE_PIECES_NMC  
             SET NMC_BG = NMC_BG + 2  
             WHERE NMC_BG > @bdp AND NMC_BG < @bdmax  
      IF @@ERROR <> 0  
      BEGIN  
         GOTO LBL_ERROR  
         RETURN  
      END  
  
      UPDATE dbo.T_NOMENCLATURE_PIECES_NMC  
             SET NMC_BG = @bdp + 1,  
                 NMC_BD = @bdp + 2,  
                 NMC_NIVEAU = @nivp  
             WHERE NMC_ID = @id  
      IF @@ERROR <> 0  
      BEGIN  
         GOTO LBL_ERROR  
         RETURN  
      END  
   END  
  
   -- Fils cadet  
   IF @mode = 'FC'  
   BEGIN  
      -- Limite sup.  
      UPDATE dbo.T_NOMENCLATURE_PIECES_NMC  
             SET NMC_BD = NMC_BD + 2  
             WHERE NMC_BD >= @bdp AND NMC_BD <= @bdmax  
      IF @@ERROR <> 0  
      BEGIN  
         GOTO LBL_ERROR  
         RETURN  
      END  
  
      -- Limite inf.  
      UPDATE dbo.T_NOMENCLATURE_PIECES_NMC  
             SET NMC_BG = NMC_BG + 2  
             WHERE NMC_BG > @bdp AND NMC_BG < @bdmax  
      IF @@ERROR <> 0  
      BEGIN  
         GOTO LBL_ERROR  
         RETURN  
      END  
  
      UPDATE dbo.T_NOMENCLATURE_PIECES_NMC  
             SET NMC_BG = @bdp,  
                 NMC_BD = @bdp + 1,  
                 NMC_NIVEAU = @nivp + 1  
             WHERE NMC_ID = @id  
      IF @@ERROR <> 0  
      BEGIN  
         GOTO LBL_ERROR  
         RETURN  
      END  
   END  
  
   -- Fils ainé  
   IF @mode = 'FA'  
   BEGIN  
      -- Limite sup.  
      UPDATE dbo.T_NOMENCLATURE_PIECES_NMC  
             SET NMC_BD = NMC_BD + 2  
             WHERE NMC_BD > @bgp AND NMC_BD <= @bdmax  
      IF @@ERROR <> 0  
      BEGIN  
         GOTO LBL_ERROR  
         RETURN  
      END  
  
      -- Limite inf.  
      UPDATE dbo.T_NOMENCLATURE_PIECES_NMC  
             SET NMC_BG = NMC_BG + 2  
             WHERE NMC_BG > @bgp AND NMC_BG < @bdmax  
      IF @@ERROR <> 0  
      BEGIN  
         GOTO LBL_ERROR  
         RETURN  
      END  
  
      UPDATE dbo.T_NOMENCLATURE_PIECES_NMC  
             SET NMC_BG = @bgp + 1,  
                 NMC_BD = @bgp + 2,  
                 NMC_NIVEAU = @nivp + 1  
             WHERE NMC_ID = @id  
      IF @@ERROR <> 0  
      BEGIN  
         GOTO LBL_ERROR  
         RETURN  
      END  
   END  
END  
ELSE  
BEGIN  
   -- L'élément et sa descendance doivent être déplacés  
  
   -- déplacement de l'élément et de sa descendance en fin de liste  
   -- Le niveau sera réactualisé ultérieurement  
   UPDATE dbo.T_NOMENCLATURE_PIECES_NMC  
          SET NMC_BG = NMC_BG + @deltab,  
              NMC_BD = NMC_BD + @deltab,  
              NMC_NIVEAU = NMC_NIVEAU - @nivd  
          WHERE NMC_BG >= @bgd AND NMC_BD <= @bdd  
   IF @@ERROR <> 0  
   BEGIN  
      GOTO LBL_ERROR  
      RETURN  
   END  
  
   -- rétablissement des bornes  
  
   -- Calcul du Delta  
   SET @deltab = @bdd - @bgd + 1  
   --  
   UPDATE dbo.T_NOMENCLATURE_PIECES_NMC  
          SET NMC_BD = NMC_BD - @deltab  
          WHERE NMC_BD > @bdd AND NMC_BG <= @bdmax  
   IF @@ERROR <> 0  
   BEGIN  
      GOTO LBL_ERROR  
      RETURN  
   END  
   --   
   UPDATE dbo.T_NOMENCLATURE_PIECES_NMC  
          SET NMC_BG = NMC_BG - @deltab  
          WHERE NMC_BG > @bdd AND NMC_BG < @bdmax  
   IF @@ERROR <> 0  
   BEGIN  
      GOTO LBL_ERROR  
      RETURN  
   END  
  
   -- On récupère d'abord les caractéristiques du parent  
   SELECT @bgp = NMC_BG, @bdp = NMC_BD, @nivp = NMC_NIVEAU   
          FROM dbo.T_NOMENCLATURE_PIECES_NMC   
          WHERE NMC_ID = @id_parent  
   IF @@ERROR <> 0  
   BEGIN  
      GOTO LBL_ERROR  
      RETURN  
   END  
  
   -- Mise en place de l'élement deplacé  
  
   -- Grand frère  
   IF @mode = 'GF'  
   BEGIN  
      -- Limite sup.  
      UPDATE dbo.T_NOMENCLATURE_PIECES_NMC  
             SET NMC_BD = NMC_BD + @deltab  
             WHERE NMC_BD > @bgp AND NMC_BD <= @bdmax  
      IF @@ERROR <> 0  
      BEGIN  
         GOTO LBL_ERROR  
         RETURN  
      END  
  
      -- Limite inf.  
      UPDATE dbo.T_NOMENCLATURE_PIECES_NMC  
             SET NMC_BG = NMC_BG + @deltab  
             WHERE NMC_BG >= @bgp AND NMC_BG < @bdmax  
      IF @@ERROR <> 0  
      BEGIN  
         GOTO LBL_ERROR  
         RETURN  
      END  
  
      -- Recadrage de la liste d'éléments déplacés  
      SET @deltab = @bdmax - @bgp + 1  
      UPDATE dbo.T_NOMENCLATURE_PIECES_NMC  
             SET NMC_BG = NMC_BG - @deltab,  
                 NMC_BD = NMC_BD - @deltab,  
                 NMC_NIVEAU = NMC_NIVEAU + @nivp  
             WHERE NMC_BG > @bdmax  
      IF @@ERROR <> 0  
      BEGIN  
         GOTO LBL_ERROR  
         RETURN  
      END  
   END  
  
   -- Petit Frère   
   IF @mode = 'PF'  
   BEGIN  
      -- Limite sup.  
      UPDATE dbo.T_NOMENCLATURE_PIECES_NMC  
             SET NMC_BD = NMC_BD + @deltab  
             WHERE NMC_BD > @bdp AND NMC_BD <= @bdmax  
      IF @@ERROR <> 0  
      BEGIN  
         GOTO LBL_ERROR  
         RETURN  
      END  
  
      -- Limite inf.  
      UPDATE dbo.T_NOMENCLATURE_PIECES_NMC  
             SET NMC_BG = NMC_BG + @deltab  
             WHERE NMC_BG > @bdp AND NMC_BG < @bdmax  
      IF @@ERROR <> 0  
      BEGIN  
         GOTO LBL_ERROR  
         RETURN  
      END  
  
      -- Recadrage de la liste d'éléments déplacés  
      SET @deltab = @bdmax - @bdp  
      UPDATE dbo.T_NOMENCLATURE_PIECES_NMC  
             SET NMC_BG = NMC_BG - @deltab,  
                 NMC_BD = NMC_BD - @deltab,  
                 NMC_NIVEAU = NMC_NIVEAU + @nivp  
             WHERE NMC_BG > @bdmax  
      IF @@ERROR <> 0  
      BEGIN  
         GOTO LBL_ERROR  
         RETURN  
      END  
   END  
  
   -- Fils cadet  
   IF @mode = 'FC'  
   BEGIN  
      -- Limite sup.  
      UPDATE dbo.T_NOMENCLATURE_PIECES_NMC  
             SET NMC_BD = NMC_BD + @deltab  
             WHERE NMC_BD >= @bdp AND NMC_BD <= @bdmax  
      IF @@ERROR <> 0  
      BEGIN  
         GOTO LBL_ERROR  
         RETURN  
      END  
  
      -- Limite inf.  
      UPDATE dbo.T_NOMENCLATURE_PIECES_NMC  
             SET NMC_BG = NMC_BG + @deltab  
             WHERE NMC_BG > @bdp AND NMC_BG < @bdmax  
      IF @@ERROR <> 0  
      BEGIN  
         GOTO LBL_ERROR  
         RETURN  
      END  
  
      -- Recadrage de la liste d'éléments déplacés  
      SET @deltab = @bdmax - @bdp + 1  
      UPDATE dbo.T_NOMENCLATURE_PIECES_NMC  
             SET NMC_BG = NMC_BG - @deltab,  
                 NMC_BD = NMC_BD - @deltab,  
                 NMC_NIVEAU = NMC_NIVEAU + @nivp + 1  
             WHERE NMC_BG > @bdmax  
      IF @@ERROR <> 0  
      BEGIN  
         GOTO LBL_ERROR  
         RETURN  
      END  
   END  
  
   -- Fils ainé  
   IF @mode = 'FA'  
   BEGIN  
      -- Limite sup.  
      UPDATE dbo.T_NOMENCLATURE_PIECES_NMC  
             SET NMC_BD = NMC_BD + @deltab  
             WHERE NMC_BD > @bgp AND NMC_BD <= @bdmax  
      IF @@ERROR <> 0  
      BEGIN  
         GOTO LBL_ERROR  
         RETURN  
      END  
  
      -- Limite inf.  
      UPDATE dbo.T_NOMENCLATURE_PIECES_NMC  
             SET NMC_BG = NMC_BG + @deltab  
             WHERE NMC_BG > @bgp AND NMC_BG < @bdmax  
      IF @@ERROR <> 0  
      BEGIN  
         GOTO LBL_ERROR  
         RETURN  
      END  
  
      -- Recadrage de la liste d'éléments déplacés  
      SET @deltab = @bdmax - @bgp  
      UPDATE dbo.T_NOMENCLATURE_PIECES_NMC  
             SET NMC_BG = NMC_BG - @deltab,  
                 NMC_BD = NMC_BD - @deltab,  
                 NMC_NIVEAU = NMC_NIVEAU + @nivp + 1  
             WHERE NMC_BG > @bdmax  
      IF @@ERROR <> 0  
      BEGIN  
         GOTO LBL_ERROR  
         RETURN  
      END  
   END  
END  
  
COMMIT TRANSACTION MOVE_NMC  
GOTO LBL_FINAL  
RETURN  
  
LBL_ERROR:  
ROLLBACK TRANSACTION MOVE_NMC  
  
LBL_FINAL:  
SET TRANSACTION ISOLATION LEVEL READ COMMITTED   
  
GO
Code sql : Sélectionner tout
1
2
3
4
5
6
7
CREATE TABLE dbo.dbo.T_NOMENCLATURE_PIECES_NMC   
(  NMC_ID T_N_ID IDENTITY NOT NULL PRIMARY KEY,  
  NMC_BG T_N_INT_POS NOT NULL ,  
  NMC_BD T_N_INT_POS NOT NULL ,  
  NMC_NIVEAU T_N_INT NOT NULL ,  
  ...  
)
Pour l'adapter à votre table spécifique, il suffit de remplacer les noms de la tables et des différentes colonnes, afin de l'adpater à votre cas.

Code sql : Sélectionner tout
EXEC dbo.P_MOVE_TRE 45, 108, 'FA', 1
Bon amusement !

Mis à jour le 24 mai 2009 SQLpro

Dans cet article sur les arbres intervallaires, je n'ai pas mentionné comment effectuer la transformation d'une table modélisée par auto référence en une table en mode intervallaire. Voici comment procéder...

La procédure ci dessous utilise du code SQL dynamique pour intégrer les données à transformer dans des tables pseudo temporaires pour ensuite les reverser dans la table d'origine. Il convient de créer préalablement les colonnes nécessaire pour recevoir les bornes gauches et droite.

Code sql : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
/******************************************************************************  
-- création d'une procédure de calcul des bornes des intervalles de l'arbre    
******************************************************************************/  
-- la procédure P_DERECURSIVE_TREE existe t-elle dans la base ?   
-- Si oui, la supprimer !  
IF EXISTS (SELECT *  
           FROM   INFORMATION_SCHEMA.ROUTINES  
           WHERE  ROUTINE_SCHEMA = 'dbo'  
             AND  ROUTINE_NAME = 'P_DERECURSIVE_TREE'  
             AND  ROUTINE_TYPE = 'PROCEDURE')  
   DROP PROCEDURE P_DERECURSIVE_TREE  
GO  
  
-- création de la fonction P_EXPLORE_DIR  
CREATE PROCEDURE dbo.P_DERECURSIVE_TREE @TABLE_SCHEMA sysname,  
                                        @TABLE_NAME   sysname,  
                                        @COL_ID       sysname,  
                                        @COL_ID_PERE  sysname,  
                                        @COL_BG       sysname,  
                                        @COL_BD       sysname   
AS  
/******************************************************************************  
* PROCÉDURE DE CALCUL D'UN ARBRE INTERVALLAIRE ACTUELLEMENT EN AUTO RÉFÉRENCE *  
*******************************************************************************  
* Frédéric Brouard   -   SQLPro   -   http://www.sqlspot.com   -   2004-06-10 *  
*******************************************************************************  
* PARAMÈTRES :                                                                *  
*    @TABLE_SCHEMA schéma SQL de la table (en principe dbo)                   *  
*    @TABLE_NAME   nom de la table                                            *  
*    @COL_ID       nom de la colonne colonne clef primaire                    *  
*    @COL_ID_PERE  nom de la col. clef étrangère en auto réf. à la clef prim. *  
*    @COL_BG       nom de la colonne borne gauche                             *  
*    @COL_BD       nom de la colonne borne droite                             *  
******************************************************************************/  
  
DECLARE @SQL NVARCHAR(4000)  
  
-- la table TMP_TREE_SQLPro existe t-elle dans la base B_DATASAPIENS_OS_FILE  
-- pour l'utilisateur courant ? Si oui, la virer !  
IF EXISTS (SELECT *  
           FROM   INFORMATION_SCHEMA.TABLES  
           WHERE  TABLE_SCHEMA = 'dbo'  
             AND  TABLE_NAME = 'TMP_TREE_SQLPro')  
   BEGIN  
      SET @SQL = 'DROP TABLE dbo.TMP_TREE_SQLPro'  
      EXEC (@SQL)  
   END  
  
-- on créé la table TMP_TREE_SQLPro pour stocker temporairement les identifiants  
-- et autorelations de la table à traiter  
CREATE TABLE dbo.TMP_TREE_SQLPro  
(CLEF     INT NOT NULL,  
 CLEF_REF INT);  
  
-- la table TMP_STACK_SQLPro existe t-elle dans la base B_DATASAPIENS_OS_FILE  
-- pour l'utilisateur courant ? Si oui, la virer !  
IF EXISTS (SELECT *  
           FROM   INFORMATION_SCHEMA.TABLES  
           WHERE  TABLE_SCHEMA = 'dbo'  
             AND  TABLE_NAME = 'TMP_STACK_SQLPro')  
   BEGIN  
      SET @SQL = 'DROP TABLE dbo.TMP_STACK_SQLPro'  
      EXEC (@SQL)  
   END  
  
-- on créé la table TMP_STACK_SQLPro pour gérer une pile afin de dérécursiver l'arbre  
CREATE TABLE dbo.TMP_STACK_SQLPro  
(PILE INTEGER NOT NULL,  
 CLEF CHAR(10) NOT NULL,  
 GAUCHE INTEGER,  
 DROITE INTEGER);  
  
-- on y insère les valeurs dedans  
SET @SQL = 'INSERT INTO dbo.TMP_TREE_SQLPro SELECT ' + @COL_ID + ', ' + @COL_ID_PERE   
         + ' FROM ' + @TABLE_SCHEMA + '.'  + @TABLE_NAME  
EXECUTE (@SQL)  
  
  
-- variables locales  
DECLARE @COMPTEUR INTEGER;  
DECLARE @MAX_CPTR INTEGER;  
DECLARE @POINTEUR INTEGER;  
  
-- initialisation  
SET @COMPTEUR = 2;  
SET @MAX_CPTR = 2 * (SELECT COUNT(*) FROM TMP_TREE_SQLPro);  
SET @POINTEUR = 1;  
  
-- insertion de la racine de l'arbre dans la pile  
INSERT INTO TMP_STACK_SQLPro  
SELECT 1, CLEF, 1, NULL  
  FROM dbo.TMP_TREE_SQLPro  
 WHERE CLEF_REF IS NULL;  
  
-- et on supprime la référence à la racine  
DELETE FROM dbo.TMP_TREE_SQLPro  
 WHERE CLEF_REF IS NULL;  
  
-- tant que l'on a pas traité toute l'enveloppe intervallaire  
WHILE @COMPTEUR <= (@MAX_CPTR)  
BEGIN  
  
-- s'il existe des lignes à traiter  
   IF EXISTS (SELECT *  
              FROM   dbo.TMP_STACK_SQLPro AS S  
                     INNER JOIN dbo.TMP_TREE_SQLPro AS T  
                           ON S.CLEF = T.CLEF_REF  
              WHERE  S.PILE = @POINTEUR)  
  
   BEGIN   
  
-- empile tant que la ligne analysée a des fils (calcul de la borne gauche)  
       INSERT INTO dbo.TMP_STACK_SQLPro  
       SELECT @POINTEUR + 1, MIN(T.CLEF), @COMPTEUR, NULL  
       FROM   dbo.TMP_STACK_SQLPro AS S  
              INNER JOIN dbo.TMP_TREE_SQLPro AS T  
                    ON S.CLEF = T.CLEF_REF  
       WHERE  S.PILE = @POINTEUR;  
-- supprime la ligne analysée  
       DELETE FROM dbo.TMP_TREE_SQLPro  
       WHERE CLEF = (SELECT CLEF  
                     FROM   dbo.TMP_STACK_SQLPro  
                     WHERE  PILE = @POINTEUR + 1);  
-- incrémente compteur et pointeur  
        SET @COMPTEUR = @COMPTEUR + 1;  
        SET @POINTEUR = @POINTEUR + 1;  
  
     END  
     ELSE  
     BEGIN   
  
-- dépile parce que que la ligne analysée n'a plus de fils (calcul de la borne droite)  
        UPDATE dbo.TMP_STACK_SQLPro  
        SET    DROITE = @COMPTEUR,  
               PILE = - PILE -- pops the Stack  
        WHERE  PILE = @POINTEUR  
  
-- incrémente compteur et décrémente pointeur  
       SET @COMPTEUR = @COMPTEUR + 1;  
       SET @POINTEUR = @POINTEUR - 1;  
  
     END;  
END;  
  
-- met à jour la table cible avec ces calculs  
SET @SQL = ' UPDATE ' + @TABLE_SCHEMA + '.' + @TABLE_NAME +  
           ' SET    ' + @COL_BG + ' = S.GAUCHE, ' +  
                        @COL_BD + ' = S.DROITE' +  
           ' FROM   dbo.TMP_STACK_SQLPro S INNER JOIN ' + @TABLE_NAME + ' T ON S.CLEF = T.'+@COL_ID  
EXEC (@SQL)  
  
-- suppression des tables pseudo temporaires  
IF EXISTS (SELECT *  
           FROM   INFORMATION_SCHEMA.TABLES  
           WHERE  TABLE_SCHEMA = 'dbo'  
             AND  TABLE_NAME = 'TMP_TREE_SQLPro')  
   BEGIN  
      SET @SQL = 'DROP TABLE dbo.TMP_TREE_SQLPro'  
      EXEC (@SQL)  
   END  
IF EXISTS (SELECT *  
           FROM   INFORMATION_SCHEMA.TABLES  
           WHERE  TABLE_SCHEMA = 'dbo'  
             AND  TABLE_NAME = 'TMP_STACK_SQLPro')  
   BEGIN  
      SET @SQL = 'DROP TABLE dbo.TMP_STACK_SQLPro'  
      EXEC (@SQL)  
   END  
  
GO
Voici maintenant comment utiliser cette procédure à traver un exemple...

Code sql : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
CREATE TABLE dbo.FAMILLE   
(FAM_ID INTEGER, FAM_LIB VARCHAR(16), FAM_PERE INTEGER)  
GO  
  
INSERT INTO dbo.FAMILLE (FAM_ID, FAM_LIB, FAM_PERE) VALUES (0, 'Transport', NULL)   
INSERT INTO dbo.FAMILLE (FAM_ID, FAM_LIB, FAM_PERE) VALUES (1, 'Terrestre', 0)   
INSERT INTO dbo.FAMILLE (FAM_ID, FAM_LIB, FAM_PERE) VALUES (2, 'Marin', 0)   
INSERT INTO dbo.FAMILLE (FAM_ID, FAM_LIB, FAM_PERE) VALUES (3, 'Aérien', 0)   
INSERT INTO dbo.FAMILLE (FAM_ID, FAM_LIB, FAM_PERE) VALUES (4, 'Voiture', 1)   
INSERT INTO dbo.FAMILLE (FAM_ID, FAM_LIB, FAM_PERE) VALUES (5, 'Camion', 1)   
INSERT INTO dbo.FAMILLE (FAM_ID, FAM_LIB, FAM_PERE) VALUES (6, 'Moto', 1)   
INSERT INTO dbo.FAMILLE (FAM_ID, FAM_LIB, FAM_PERE) VALUES (7, 'Vélo', 1)   
INSERT INTO dbo.FAMILLE (FAM_ID, FAM_LIB, FAM_PERE) VALUES (8, 'Hélico', 3)   
INSERT INTO dbo.FAMILLE (FAM_ID, FAM_LIB, FAM_PERE) VALUES (9, 'Avion', 3)   
INSERT INTO dbo.FAMILLE (FAM_ID, FAM_LIB, FAM_PERE) VALUES (10, 'ULM', 3)   
INSERT INTO dbo.FAMILLE (FAM_ID, FAM_LIB, FAM_PERE) VALUES (11, 'Fusée', 3)   
INSERT INTO dbo.FAMILLE (FAM_ID, FAM_LIB, FAM_PERE) VALUES (12, 'Parachute', 3)   
INSERT INTO dbo.FAMILLE (FAM_ID, FAM_LIB, FAM_PERE) VALUES (13, 'Planeur', 3)   
INSERT INTO dbo.FAMILLE (FAM_ID, FAM_LIB, FAM_PERE) VALUES (14, 'Voilier', 2)   
INSERT INTO dbo.FAMILLE (FAM_ID, FAM_LIB, FAM_PERE) VALUES (15, 'Paquebot', 2)   
INSERT INTO dbo.FAMILLE (FAM_ID, FAM_LIB, FAM_PERE) VALUES (16, 'Planche à voile', 2)   
INSERT INTO dbo.FAMILLE (FAM_ID, FAM_LIB, FAM_PERE) VALUES (17, 'Trail', 6)   
INSERT INTO dbo.FAMILLE (FAM_ID, FAM_LIB, FAM_PERE) VALUES (18, 'Side-car', 6)   
INSERT INTO dbo.FAMILLE (FAM_ID, FAM_LIB, FAM_PERE) VALUES (19, 'Civil', 9)   
INSERT INTO dbo.FAMILLE (FAM_ID, FAM_LIB, FAM_PERE) VALUES (20, 'Tourisme', 9)   
INSERT INTO dbo.FAMILLE (FAM_ID, FAM_LIB, FAM_PERE) VALUES (21, 'Militaire', 9)  
GO  
  
  
/******************************************************************************  
-- transformation du mode auto référence en mode intervallaire  
******************************************************************************/  
  
-- modification de la table d'origine pour ajout des bornes gauches et droite :  
ALTER TABLE dbo.FAMILLE ADD FAM_BG INT;  
ALTER TABLE dbo.FAMILLE ADD FAM_BD INT;  
GO  
  
-- exécution de la transformation  
EXEC dbo.P_DERECURSIVE_TREE 'dbo', 'FAMILLE', 'FAM_ID', 'FAM_PERE', 'FAM_BG', 'FAM_BD'  
GO  
  
-- indexation  
CREATE INDEX X_FAM_RECURINTERVAL ON dbo.FAMILLE (FAM_BG, FAM_BD) WITH FILLFACTOR = 90;  
  
/******************************************************************************  
-- ajout du niveau  
******************************************************************************/  
  
-- modification de la table d'origine pour ajout du niveau :  
ALTER TABLE dbo.FAMILLE ADD FAM_NIVEAU INT;  
GO  
  
-- mise à jour du niveau :  
UPDATE dbo.FAMILLE  
SET    FAM_NIVEAU = N  
FROM   dbo.FAMILLE AS F  
INNER JOIN (SELECT *, (SELECT COUNT(*)   
                       FROM   dbo.FAMILLE AS Tin   
                       WHERE  Tin.FAM_BG < Tout.FAM_BG  
                         AND  Tin.FAM_BD > Tout.FAM_BD) AS N  
            FROM   dbo.FAMILLE AS Tout) AS FN  
            ON F.FAM_ID = FN.FAM_ID;  
  
-- vérification :  
SELECT *  
FROM   dbo.FAMILLE;
CQFD !

Mis à jour le 24 mai 2009 SQLpro

Code tsql : Sélectionner tout
1
2
3
4
5
6
7
8
9
SET ROWCOUNT 3 
  
CREATE TABLE #T (OPT NVARCHAR(128), VAL SQL_VARIANT); 
INSERT INTO #T EXEC ('DBCC USEROPTIONS'); 
SELECT VAL FROM #T WHERE OPT = 'rowcount'; 
  
VAL 
-------------------- 
3
Cependant à partir de 2005 l'utilisation de TOP n ne pose pas de problème vu que vous pouvez faire un TOP @N

Mis à jour le 11 juillet 2009 SQLpro

Proposer une nouvelle réponse sur la FAQ

Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour ça


Réponse à la question

Liens sous la question
précédent sommaire suivant
 

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2017 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

 
Contacter le responsable de la rubrique SQL-Server