¿Por qué un CTE debe comenzar con un punto y coma?


14

Estaba mirando una publicación en StackOverflow donde Aaron Bertrand propone usar un CTE en lugar de una tabla de números, que es una forma elegante de realizar la tarea en cuestión. Mi pregunta es, ¿por qué la primera línea del CTE comienza con un punto y coma?

;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!

¿Es esto para garantizar que la instrucción WITH no se analice en una anterior SELECTo algo así? No veo nada en SQL Server 2005 BOL sobre el uso de un punto y coma antes del WITH.


Respuestas:


26

Siempre lo hago cuando publico aquí o en StackOverflow porque WITH, dado que la palabra clave está sobrecargada, el comando anterior requiere un punto y coma final. Si pego una muestra de código que usa un CTE, inevitablemente algún usuario lo pegará en su código existente, y la declaración anterior no tendrá el punto y coma. Entonces el código se rompe y recibo quejas como:

¡Tu código se rompió! Recibí este mensaje de error:

Incorrect syntax near 'WITH'...

Si bien me gustaría creer que la gente está mejorando al terminar siempre sus declaraciones con un punto y coma , prefiero evitar el ruido y siempre incluirlo. A algunas personas no les gusta, pero <shrug />. Puede incluir tantos puntos y coma antes o después de una declaración válida como desee. Esto es valido:

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

Por lo tanto, no hay daño en que haya un punto y coma adicional precediendo a una declaración que, por definición, lo requiere. Es más seguro hacerlo incluso si no es tan bonito.

Tiene que estar redactado de manera extraña para entenderlo, pero "no terminar una declaración válida con un punto y coma" en realidad está en desuso desde SQL Server 2008. Entonces, como lo describo en la publicación del blog, hago un enlace arriba, incluso en los casos en que no es necesario omitir un error, debe usarse donde sea válido. Puedes ver esto aquí:

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

(Busque en la última página "punto y coma")

Por supuesto, no sería SQL Server si no hubiera excepciones. Prueba esto:

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

No es la única excepción a la regla, pero es la que me parece menos intuitiva.


1
En 2012, incluso recibo el mismo mensaje de error, pero solo por el punto y coma después de END TRY: i.stack.imgur.com/rc6dw.png : si elimino ese punto y coma, todo funciona.
Aaron Bertrand

Creo que no puede poner un punto y coma antes BEGIN CATCHsimplemente porque es parte de una sola declaración compuesta introducida con BEGIN TRY. Es lo mismo que poner un punto y coma antes de una IFdeclaración ELSE.
Andriy M

@AndriyM He tenido acceso a una conversación mucho más detallada sobre las reglas aquí. Lo mencioné porque es una sorpresa para todos los que lo ven, no porque no entiendo la razón. :-)
Aaron Bertrand

10

Esto es para garantizar que no se incluya en ninguna declaración anterior, ya que WITHpuede servir para una variedad de propósitos en T-SQL.

Si es la primera declaración del lote, no creo que lo necesite.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.