Ao verificar algum código na web e scripts gerados pelo SQL Server Management Studio, observei que algumas instruções terminam com ponto e vírgula.
Então, quando devo usá-lo?
Ao verificar algum código na web e scripts gerados pelo SQL Server Management Studio, observei que algumas instruções terminam com ponto e vírgula.
Então, quando devo usá-lo?
Respostas:
De um artigo do 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, foi possível codificar o T-SQL por anos sem encontrar um ponto e vírgula.
Uso
Há duas situações nas quais você deve usar o ponto e vírgula. A primeira situação é onde você usa uma CTE (Common Table Expression) e a CTE não é a primeira instrução do lote. A segunda é onde você emite uma declaração do Service Broker e a declaração do Service Broker não é a primeira no lote.
THROW
uma declaração do Service Broker? Precisamos incluir um ponto-e-vírgula antes de um lançamento neste exemplo:BEGIN ;THROW @Error, 'Invalid FundingID', 2; RETURN END
MERGE
também por exemplo). Como mencionado em outras respostas, no padrão ANSI eles são obrigados
Por padrão, as instruções SQL são finalizadas com ponto e vírgula. Você usa um ponto-e-vírgula para encerrar instruções, a menos que (raramente) tenha definido um novo terminador de instruções.
Se você estiver enviando apenas uma declaração, tecnicamente poderá dispensar o terminador da declaração; em um script, como você está enviando mais de uma declaração, é necessário.
Na prática, sempre inclua o terminador, mesmo se você estiver apenas enviando uma instrução para o banco de dados.
Editar: em resposta àqueles que dizem que os terminadores de instruções não são exigidos por [RDBMS específico], embora isso possa ser verdade, eles são exigidos pelo ANSI SQL Standard. Em toda a programação, se podemos aderir a um padrão sem perda de funcionalidade, devemos fazê-lo, porque nem nosso código nem nossos hábitos estão vinculados a um fornecedor proprietário.
Com alguns compiladores C, é possível que o retorno principal seja nulo, mesmo que o Standard exija que main retorne int. Mas fazer isso torna nosso código e nós mesmos menos portáteis.
A maior dificuldade em programar efetivamente não é aprender coisas novas, é desaprender maus hábitos. Na medida em que podemos evitar adquirir maus hábitos em primeiro lugar, é uma vitória para nós, para nosso código e para qualquer pessoa que esteja lendo ou usando 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:
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 banco de dados. O SQL Server requer o ponto e vírgula apenas em casos específicos - mas nos casos em que não é necessário um ponto e vírgula, o uso de um não causa problemas. Eu recomendo fortemente que você adote a prática de encerrar todas as declarações com ponto e vírgula. Isso não apenas melhora 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 que o SQL Server produz nem sempre é muito clara.)
E o mais importante:
A documentação do SQL Server indica que não encerrar instruções T-SQL com ponto-e-vírgula é um recurso obsoleto. Isso significa que o objetivo 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 onde atualmente não é necessário.
Fonte: Fundamentos de T-SQL do Microsoft SQL Server 2012 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
BEGIN TRY
BEGIN TRAN
SELECT 1/0 AS CauseAnException;
COMMIT
END TRY
BEGIN CATCH
SELECT ERROR_MESSAGE();
THROW
END CATCH
not using them
técnica obrigatória e obsoleta, você deve usá-los. Caso contrário, existe o risco de sofrer no futuro. Se você não estiver planejando atualizar / trabalho interruptor e sempre vai trabalhar com SQL Server 2000 você está seguro :-)
Incorrect syntax near 'THROW'.
SQL Server 2008 (10.0.6241.0), que é a versão com a qual tenho de lidar no trabalho. Funciona como mostrado em 2012. Fui convencido a começar a usar ponto e vírgula por causa da descontinuação. Não espero que seja um problema em 2008 na maioria das vezes.
Se eu ler isso corretamente, será necessário usar ponto-e-vírgula para finalizar as instruções TSQL. http://msdn.microsoft.com/en-us/library/ms143729%28v=sql.120%29.aspx
EDIT: Encontrei um plug-in para o SSMS 2008R2 que irá formatar seu script e adicionar os pontos e vírgulas. Eu acho que ainda está na versão beta ...
http://www.tsqltidy.com/tsqltidySSMSAddin.aspx
EDIT: Encontrei uma ferramenta / plugin grátis ainda melhor chamada ApexSQL ... http://www.apexsql.com/
Opinião pessoal: use-os somente onde for necessário. (Veja a resposta do TheTXI acima para a lista necessária.)
Como o compilador não exige, você pode colocá-los por toda parte, mas por quê? O compilador não lhe dirá onde você esqueceu um, então você terminará com um uso inconsistente.
[Esta opinião é específica para o SQL Server. Outros bancos de dados podem ter requisitos mais rigorosos. Se você estiver escrevendo o SQL para executar em vários bancos de dados, seus requisitos poderão variar.]
tpdi afirmou acima, "em um script, como você está enviando mais de uma declaração, você precisa dela". Na verdade, isso 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';
Resultado:
Semicolons are optional
Semicolons are optional
Semicolons are optional
Semicolons are optional
Ainda tenho muito a aprender sobre o T-SQL, mas, ao elaborar algum código para uma transação (e basear o código em exemplos de stackoverflow e outros sites), encontrei um caso em que parece que é necessário um ponto-e-vírgula e, se estiver faltando, a instrução parece não ser executada e nenhum erro é gerado. Isso não parece ser coberto em nenhuma das respostas acima. (Isso estava usando o MS SQL Server 2012.)
Depois que a transação funcionou da maneira que eu queria, decidi colocar um try-catch em volta, para que, se houver algum erro, ela seja revertida. 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ê para 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, como nenhum erro (sintaxe ou não) é relatado, não ficou imediatamente claro qual era o problema.
Por outro lado, ROLLBACK TRANSACTION parece funcionar igualmente bem no bloco BEGIN CATCH com ou sem ponto e vírgula.
Pode haver alguma lógica para isso, mas parece arbitrário e Alice no País das Maravilhas.
COMMIT TRANSACTION
aceita um nome opcional de transação / ponto de salvamento (que ele ignorará). Sem um ponto-e-vírgula final, COMMIT TRANSACTION
pode comer o próximo símbolo se analisar como um identificador, o que pode mudar radicalmente a semântica do código. Se isso resultar em um erro, o CATCH
gatilho pode ser disparado sem que COMMIT
ele tenha sido executado. Por outro lado, embora ROLLBACK TRANSACTION
também aceite um identificador opcional como este, um erro na análise de lá provavelmente resultará na reversão da transação de qualquer maneira.
Parece que ponto e vírgula não deve ser usado em conjunto com operações de cursor: OPEN
, FETCH
, CLOSE
eDEALLOCATE
. Só perdi algumas horas com isso. Eu examinei atentamente o BOL e notei que [;] não é mostrado na sintaxe para essas instruções do cursor !!
Então eu tive:
OPEN mycursor;
e isso me deu o erro 16916.
Mas:
OPEN mycursor
trabalhou.
De acordo com as convenções de sintaxe 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, será necessário em uma versão futura.
(veja também o comentário de @gerryLowry)
Ao usar uma instrução DISABLE ou ENABLE TRIGGER em um lote que contenha outras instruções, a instrução imediatamente antes de terminar com ponto e vírgula. Caso contrário, você receberá um erro de sintaxe. Eu arranquei meu cabelo com este ... E depois, tropecei neste item do MS Connect sobre a mesma coisa. Está fechado como não será corrigido.
veja aqui
Nota: Isso responde à pergunta como está escrita, mas não ao problema como indicado. Adicionando aqui, pois as pessoas o procurarão
O ponto-e-vírgula também é usado antes 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 números inteiros [1..10]. Isso é feito criando uma tabela apenas com o valor 1 e recorrendo até atingir 10.
Se você deseja obter erros aleatórios de tempo limite do comando no SQLServer, deixe o ponto e vírgula no final de suas seqüências de caracteres CommandText.
Não sei se isso está documentado em algum lugar ou se é um bug, mas acontece e aprendi isso com uma experiência amarga.
Eu tenho exemplos verificáveis e reproduzíveis usando o SQLServer 2008.
tcp -> Na prática, sempre inclua o terminador, mesmo se você estiver apenas enviando uma instrução para o banco de dados.
Ponto-e-vírgula 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)