Quando devo usar ponto-e-vírgula no SQL Server?

Ao verificar algum código na Web e scripts gerados pelo SQL Server Management Studio, notei que algumas instruções são finalizadas com um ponto-e-vírgula.

Então, quando devo usá-lo?

De um artigo SQLServerCentral.Com de Ken Powers:

O ponto e vírgula

O caractere ponto-e-vírgula é um terminador de instrução. Faz parte do padrão ANSI SQL-92, mas nunca foi usado no Transact-SQL. De fato, era possível codificar o T-SQL por anos sem nunca encontrar um ponto-e-vírgula.

Uso

Existem duas situações em que você deve usar o ponto-e-vírgula. A primeira situação é onde você usa uma Expressão de Tabela Comum (CTE) e o CTE não é a primeira instrução no lote. A segunda é onde você emite uma instrução do Service Broker e a instrução do Service Broker não é a primeira instrução no lote.

Por padrão, as instruções SQL são finalizadas com ponto e vírgula. Você usa um ponto-e-vírgula para encerrar as instruções, a menos que você (raramente) defina um novo terminador de instrução.

Se você está enviando apenas uma declaração, tecnicamente você pode dispensar o terminador de instruções; em um script, como você está enviando mais de uma declaração, você precisa disso.

Na prática, sempre inclua o terminador, mesmo se você estiver enviando apenas uma instrução para o database.

Edit: em resposta àqueles dizendo que os terminadores de instrução não são requeridos por [determinado RDBMS], embora isso possa ser verdade, eles são requeridos pelo ANSI SQL Standard. Em toda programação, se pudermos aderir a um padrão sem perda de funcionalidade, devemos, porque, então, nem nosso código nem nossos hábitos estão vinculados a um único fornecedor.

Com alguns compiladores C, é possível ter o retorno principal vazio, mesmo que o Padrão requeira que o main retorne int. Mas isso faz com que nosso código, e nós mesmos, seja menos portável.

A maior dificuldade em programar efetivamente não é aprender coisas novas, é desaprender maus hábitos. Na medida em que podemos evitar a aquisição de maus hábitos em primeiro lugar, é uma vitória para nós, para o nosso código e para quem lê ou usa o nosso código.

No SQL2008 BOL eles dizem que nos próximos lançamentos serão necessários pontos e vírgulas. Portanto, sempre use-o.

Referência:

  • Convenções de syntax Transact-SQL (Transact-SQL)
  • Recursos obsoletos do Mecanismo de Banco de Dados no SQL Server 2008 R2 (seção “Recursos não suportados em uma versão futura do SQL Server”, área “Transact-SQL”)

Se eu ler isso corretamente, será necessário usar ponto e vírgula para finalizar as instruções TSQL. http://msdn.microsoft.com/pt-br/library/ms143729%28v=sql.120%29.aspx

EDIT: Eu encontrei um plug-in para o SSMS 2008R2 que irá formatar o seu script e adicione os pontos e vírgulas. Eu acho que ainda está em beta embora …

http://www.tsqltidy.com/tsqltidySSMSAddin.aspx

EDIT: Eu encontrei uma ferramenta / plugin grátis ainda melhor chamada ApexSQL … http://www.apexsql.com/

Você deve usá-lo.

A prática de usar um ponto-e-vírgula para finalizar instruções é padrão e, de fato, é um requisito em várias outras plataformas de database. O SQL Server requer o ponto-e-vírgula apenas em casos específicos, mas nos casos em que um ponto-e-vírgula não é necessário, o uso de um não causa problemas. Eu recomendo fortemente que você adote a prática de terminar todas as declarações com um ponto e vírgula. Não só isso vai melhorar a legibilidade do seu código, mas em alguns casos, pode poupar algum sofrimento. (Quando um ponto-e-vírgula é necessário e não é especificado, a mensagem de erro produzida pelo SQL Server nem sempre é muito clara.)

E o mais importante:

A documentação do SQL Server indica que não terminar as instruções T-SQL com um ponto-e-vírgula é um recurso obsoleto. Isso significa que o objective a longo prazo é impor o uso do ponto-e-vírgula em uma versão futura do produto. Essa é mais uma razão para adquirir o hábito de encerrar todas as suas declarações, mesmo quando não for necessário.

Fonte: Microsoft SQL Server 2012 Fundamentos de T-SQL por Itzik Ben-Gan.


Um exemplo de por que você sempre deve usar ; são as duas consultas a seguir (copiadas desta postagem ):

 BEGIN TRY BEGIN TRAN SELECT 1/0 AS CauseAnException COMMIT END TRY BEGIN CATCH SELECT ERROR_MESSAGE() THROW END CATCH 

insira a descrição da imagem aqui

 BEGIN TRY BEGIN TRAN SELECT 1/0 AS CauseAnException; COMMIT END TRY BEGIN CATCH SELECT ERROR_MESSAGE(); THROW END CATCH 

insira a descrição da imagem aqui

Opinião pessoal: use-os somente onde forem necessários. (Veja a resposta da TheTXI acima para a lista requerida.)

Já que o compilador não precisa deles, você pode colocá-los em todos os lugares, mas por quê? O compilador não lhe dirá onde você esqueceu um, então você terminará com uso inconsistente.

[Esta opinião é específica para o SQL Server. Outros bancos de dados podem ter requisitos mais rigorosos. Se você estiver escrevendo SQL para executar em vários bancos de dados, seus requisitos podem variar.]

tpdi afirmou acima, “em um script, como você está enviando mais de uma declaração, você precisa dele.” Isso na verdade não está correto. Você não precisa deles.

 PRINT 'Semicolons are optional' PRINT 'Semicolons are optional' PRINT 'Semicolons are optional'; PRINT 'Semicolons are optional'; 

Saída:

 Semicolons are optional Semicolons are optional Semicolons are optional Semicolons are optional 

Eu ainda tenho muito a aprender sobre o T-SQL, mas ao trabalhar em algum código para uma transação (e baseando código em exemplos de stackoverflow e outros sites) eu encontrei um caso em que parece que um ponto e vírgula é necessário e se estiver faltando, a declaração não parece ser executada e nenhum erro é levantado. Isso não parece estar coberto em nenhuma das respostas acima. (Isso estava usando o MS SQL Server 2012.)

Uma vez que eu tive a transação funcionando do jeito que eu queria, decidi colocar um try-catch em torno dele, então se houver algum erro, ele será revertido. Somente depois de fazer isso, a transação não foi confirmada (o SSMS confirma isso ao tentar fechar a janela com uma boa mensagem alertando você sobre o fato de que há uma transação não confirmada.

Então, é isso

 COMMIT TRANSACTION 

fora de um bloco BEGIN TRY / END TRY funcionou bem para confirmar a transação, mas dentro do bloco tinha que ser

 COMMIT TRANSACTION; 

Observe que não há erro ou aviso fornecido e nenhuma indicação de que a transação ainda não foi confirmada até tentar fechar a guia de consulta.

Felizmente isso causa um problema tão grande que é imediatamente óbvio que existe um problema. Infelizmente, uma vez que nenhum erro (syntax ou outro) é relatado, não ficou imediatamente óbvio qual era o problema.

Contrariamente, ROLLBACK TRANSACTION parece funcionar igualmente bem no bloco BEGIN CATCH com ou sem ponto e vírgula.

Pode haver alguma lógica nisso, mas parece arbitrário e Alice no País das Maravilhas.

De acordo com convenções de syntax Transact-SQL (Transact-SQL) (MSDN)

Terminador de instruções Transact-SQL. Embora o ponto-e-vírgula não seja necessário para a maioria das instruções nesta versão do SQL Server, ele será necessário em uma versão futura.

(veja também o comentário de @gerryLowry)

Parece que os ponto-e-vírgulas não devem ser usados ​​em conjunto com as operações do cursor: OPEN, FETCH, CLOSE e DEALLOCATE. Eu só perdi algumas horas com isso. Eu dei uma olhada de perto no BOL e notei que [;] não é mostrado na syntax dessas instruções do cursor !!

Então eu tive: ABRIR mycursor; e isso me deu erro 16916.

Mas: OPEN mycursor funcionou.

Ponto-e-vírgulas nem sempre funcionam em instruções SELECT compostas.

Compare essas duas versões diferentes de uma instrução SELECT composta trivial.

O código

 DECLARE @Test varchar(35); SELECT @Test= (SELECT (SELECT (SELECT 'Semicolons do not always work fine.';););); SELECT @Test Test; 

retorna

 Msg 102, Level 15, State 1, Line 5 Incorrect syntax near ';'. 

No entanto, o código

 DECLARE @Test varchar(35) SELECT @Test= (SELECT (SELECT (SELECT 'Semicolons do not always work fine.'))) SELECT @Test Test 

retorna

 Test ----------------------------------- Semicolons do not always work fine. (1 row(s) affected) 

Ao usar uma instrução DISABLE ou ENABLE TRIGGER em um lote que tenha outras instruções, a instrução antes dela deve terminar com um ponto-e-vírgula. Caso contrário, você receberá um erro de syntax. Eu rasguei meu cabelo com este … E depois, eu tropecei neste item do MS Connect sobre a mesma coisa. Está fechado e não corrige.

veja aqui

Nota: Isto responde à questão como está escrita, mas não ao problema como indicado. Adicionando aqui, já que as pessoas estarão procurando por ele

O ponto e vírgula também é usado antes do WITH em declarações CTE recursivas:

 ;WITH Numbers AS ( SELECT n = 1 UNION ALL SELECT n + 1 FROM Numbers WHERE n+1 <= 10 ) SELECT n FROM Numbers 

Esta consulta irá gerar um CTE chamado Numbers, que consiste em inteiros [1..10]. Isso é feito criando uma tabela apenas com o valor 1 e recursando até chegar a 10.

Se você gosta de obter erros randoms de tempo limite de comando no SQLServer, em seguida, deixe o ponto e vírgula no final de suas seqüências de caracteres CommandText.

Eu não sei se isso está documentado em algum lugar ou se é um bug, mas acontece e eu aprendi isso com uma experiência amarga.

Eu tenho exemplos verificáveis ​​e reproduzíveis usando o SQL Server 2008.

aka -> Na prática, sempre inclua o terminador mesmo se você estiver enviando apenas uma instrução para o database.