Perché un CTE dovrebbe iniziare con un punto e virgola?


14

Stavo solo guardando un post su StackOverflow in cui Aaron Bertrand propone di utilizzare un CTE invece di una tabella numerica, che è un modo elegante di eseguire l'attività a portata di mano. La mia domanda è: perché la prima riga del CTE inizia con un punto e virgola?

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

Questo per garantire che l'istruzione WITH non venga analizzata in un precedente SELECTo qualcosa del genere? In SQL Server 2005 BOL non vedo nulla sull'uso di un punto e virgola prima del WITH.


Risposte:


26

Lo faccio sempre quando pubblico qui o su StackOverflow perché per WITH- poiché la parola chiave è sovraccarica - il comando precedente richiede un punto e virgola che termina. Se incollo un esempio di codice che utilizza un CTE, inevitabilmente alcuni utenti lo incolleranno nel loro codice esistente e l'istruzione precedente non avrà il punto e virgola. Quindi il codice si rompe e ricevo lamentele come:

Il tuo codice si è rotto! Ho ricevuto questo messaggio di errore:

Incorrect syntax near 'WITH'...

Mentre mi piacerebbe credere che le persone stiano migliorando nel porre sempre fine alle loro dichiarazioni con un punto e virgola , preferirei anticipare il rumore e includerlo sempre. Ad alcune persone non piace, ma <shrug />. Puoi includere tutti i punti e virgola prima o dopo un'istruzione valida che desideri. Questo è valido:

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

Quindi non vi è alcun danno nel fatto che ci sia un punto e virgola in più che precede un'affermazione che per definizione lo richiede. È più sicuro farlo anche se non è così carino.

Deve essere formulato in modo strano per ottenere il punto, ma "non terminare un'istruzione valida con un punto e virgola" è in realtà deprecato da SQL Server 2008. Quindi, come descrivo nel post del blog, mi collego a sopra, anche nei casi in cui non è necessario bypassare un errore, dovrebbe essere usato ovunque valido. Puoi vederlo qui:

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

(Cerca "semi-colon" nell'ultima pagina)

Ovviamente non sarebbe SQL Server se non ci fossero eccezioni. Prova questo:

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

Non è l'unica eccezione alla regola, ma è quella che trovo più poco intuitiva.


1
Nel 2012 ricevo anche lo stesso messaggio di errore, ma solo a causa dei punti e virgola dopo END TRY: i.stack.imgur.com/rc6dw.png - se rimuovo quel punto e virgola, tutto funziona.
Aaron Bertrand

Penso che non puoi mettere un punto e virgola prima BEGIN CATCHsemplicemente perché fa parte di una singola istruzione composta introdotta con BEGIN TRY. È come mettere un punto e virgola prima di una IFdichiarazione ELSE.
Andriy M,

@AndriyM Sono stato a conoscenza di una conversazione molto più dettagliata sulle regole qui. L'ho menzionato perché è una sorpresa per tutti coloro che lo incontrano, non perché non capisco il motivo. :-)
Aaron Bertrand

10

Questo per garantire che non sia incluso in nessuna delle precedenti dichiarazioni poiché WITHpuò servire a vari scopi in T-SQL.

Se è la prima affermazione nel batch, non penso che tu ne abbia bisogno.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.