Pourquoi un CTE devrait-il commencer par un point-virgule?


14

Je regardais juste un article sur StackOverflow où Aaron Bertrand propose d'utiliser un CTE au lieu d'une table de nombres, ce qui est une manière élégante d'effectuer la tâche à accomplir. Ma question est la suivante: pourquoi la première ligne du CTE commence-t-elle par un point-virgule?

;WITH n AS (SELECT TOP (10000) n FROM 
  (SELECT n = ROW_NUMBER() OVER
    (ORDER BY s1.[object_id])
    FROM sys.all_objects AS s1
    CROSS JOIN sys.all_objects AS s2
  ) AS x ORDER BY n
)
SELECT n FROM n ORDER BY n; -- look ma, no gaps!

Est-ce pour s'assurer que l'instruction WITH n'est pas analysée dans un précédent SELECTou quelque chose? Je ne vois rien dans SQL Server 2005 BOL concernant l'utilisation d'un point-virgule avant le WITH.


Réponses:


26

Je le fais toujours lors de la publication ici ou sur StackOverflow car pour WITH- puisque le mot-clé est surchargé - la commande précédente nécessite un point-virgule de fin. Si je colle un exemple de code qui utilise un CTE, inévitablement certains utilisateurs le colleront dans leur code existant, et l'instruction précédente n'aura pas le point-virgule. Donc le code casse, et je reçois des plaintes comme:

Votre code s'est cassé! J'ai reçu ce message d'erreur:

Incorrect syntax near 'WITH'...

Bien que j'aimerais croire que les gens sont de mieux en mieux pour toujours terminer leurs déclarations avec un point-virgule , je préfère prévenir le bruit et l'inclure simplement. Certaines personnes ne l'aiment pas, mais <shrug />. Vous pouvez inclure autant de points-virgules avant ou après une instruction valide que vous le souhaitez. Ceci est valable:

;;;;SELECT 1;;;;;;;;;;;;SELECT 2;;;;;;;;SELECT 3;;;;;

Il n'y a donc aucun mal à ce qu'il y ait un point-virgule supplémentaire précédant une déclaration qui, par définition, l'exige. C'est plus sûr de le faire même si ce n'est pas si joli.

Il doit être formulé bizarrement pour faire passer le message, mais «ne pas terminer une instruction valide par un point-virgule» est en fait obsolète depuis SQL Server 2008. Donc, comme je le décris dans le billet de blog auquel je renvoie ci-dessus, même dans les cas où il n'est pas nécessaire de contourner une erreur, il doit être utilisé partout où il est valide. Vous pouvez le voir ici:

http://msdn.microsoft.com/en-us/library/ms143729.aspx

(Recherchez la dernière page pour "point-virgule")

Bien sûr, ce ne serait pas SQL Server s'il n'y avait pas d'exceptions. Essaye ça:

BEGIN TRY;
  SELECT 1/1;
END TRY;
BEGIN CATCH;
  SELECT 1/1;
END CATCH;

Ce n'est pas la seule exception à la règle, mais c'est celle que je trouve la moins intuitive.


1
En 2012 même, je reçois le même message d'erreur, mais uniquement à cause du point-virgule après END TRY: i.stack.imgur.com/rc6dw.png - si je supprime ce point-virgule, tout fonctionne.
Aaron Bertrand

Je pense que vous ne pouvez pas mettre un point-virgule avant BEGIN CATCHsimplement parce qu'il fait partie d'une seule instruction composée introduite avec BEGIN TRY. C'est la même chose que de mettre un point-virgule avant une IFdéclaration ELSE.
Andriy M

@AndriyM J'ai eu accès à une conversation beaucoup plus détaillée sur les règles ici. Je l'ai mentionné parce que c'est une surprise pour tous ceux qui le rencontrent, pas parce que je ne comprends pas la raison. :-)
Aaron Bertrand

10

Cela permet de s'assurer qu'il n'est inclus dans aucune instruction précédente car il WITHpeut servir à diverses fins dans T-SQL.

S'il s'agit de la première instruction du lot, je ne pense pas que vous en ayez besoin.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.