Eu estava olhando uma postagem no StackOverflow onde Aaron Bertrand propõe o uso de um CTE em vez de uma tabela de números, que é uma maneira elegante de executar a tarefa em questão. Minha dúvida é: por que a primeira linha do CTE começa com ponto e vírgula?
;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!
Isso é para garantir que a instrução WITH não seja analisada em uma anterior SELECT
ou algo assim? Não vejo nada no SQL Server 2005 BOL sobre o uso de ponto e vírgula antes de WITH.
Eu sempre faço isso ao postar aqui ou no StackOverflow porque
WITH
- já que a palavra-chave está sobrecarregada - o comando anterior requer um ponto e vírgula de terminação. Se eu colar um exemplo de código que usa um CTE, inevitavelmente algum usuário o colará em seu código existente e a instrução anterior não terá o ponto e vírgula. Então o código quebra e recebo reclamações como:Embora eu goste de acreditar que as pessoas estão ficando melhores em sempre terminar suas declarações com um ponto e vírgula , prefiro antecipar o ruído e sempre incluí-lo. Algumas pessoas não gostam, mas
<shrug />
. Você pode incluir quantos pontos-e-vírgulas quiser antes ou depois de uma instrução válida. Isso é válido:Portanto, não há mal nenhum em haver um ponto e vírgula extra precedendo uma instrução que, por definição, o exija. É mais seguro fazê-lo, mesmo que não seja tão bonito.
Tem que ser escrito de maneira estranha para entender, mas "não terminar uma instrução válida com um ponto e vírgula" está obsoleto desde o SQL Server 2008. Portanto, conforme descrevo na postagem do blog acima, mesmo nos casos em que não é necessário ignorar um erro, deve ser usado sempre que for válido. Você pode ver isso aqui (e esta entrada existe há várias versões):
(pesquise nesta página por
semicolon
)Claro que não seria SQL Server se não houvesse exceções. Tente isto:
Não é a única exceção à regra, mas é a que considero menos intuitiva.
Isso é para garantir que não seja incluído em nenhuma instrução anterior, pois
WITH
pode servir a vários propósitos no T-SQL.Se for a primeira instrução do lote, acho que você não precisa.
Não deveria. Em vez disso, a instrução anterior deve ser encerrada corretamente.
Da documentação para
WITH common_table_expression
:Se você decidir usar um terminador de instrução extra por qualquer motivo, sugiro colocar o terminador em uma linha separada com um comentário explicando por que ele está lá:
Isso evita enganar as pessoas fazendo-as pensar que faz parte da sintaxe de expressão de tabela comum, o que não é.