A GO
declaração do SQL Server me causou grande curiosidade e não sei muito como usá-la corretamente.
Percebi que consultas com ou sem GO
não retornam erros e parecem funcionar da mesma forma, então qual é o propósito disso e por que devo usá-lo?
E qual é a diferença entre ponto e vírgula ;
e GO
no final de uma consulta?
GO
não faz parte da linguagem TSQL. É um separador de lote usado pelo SQLCMD e SSMS.Instruções de Utilitários do SQL Server - GO
Originou-se com as interfaces de linha de comando e persiste no sqlcmd até hoje. Você pode gravar um lote em várias linhas na interface de linha de comando e o lote não é enviado ao servidor até que você digite
go
.Você pode configurar o que usar para um separador de lote no SSMS.
GO
é o padrão, mas pode ser qualquer outra coisa.Ele divide o comando em lotes individuais.
Por exemplo, o escopo das variáveis termina com
GO
.;
separa comandos, mas não encerra o escopo.GO
separa os lotes e encerra o escopo.Você pode pensar nisso como se todo o comando fosse dividido
GO
e cada parte fosse executada por si só.ou seja.
Isso funciona:
Mas isso não funciona:
Estas são as explicações:
;
= É um terminador de instrução . Não é obrigatório , mas pode ser um dia . por enquanto você DEVE usá-lo em duas situações:GO
= É um separador de lote . Ele diz ao SQL Server "pare aqui e execute todo o código anterior antes de prosseguir" . Não é obrigatório, mas há um recurso para você: se você escreverGO 10
,GO 100
,GO 1000
ele executará o mesmo lote de código10
,100
,1000
vezesGO
não significa nada para o próprio SQL Server, mas é interpretado pelas ferramentas (como SSMS ou SQLCMD) que enviam seus scripts para o SQL Server. Algumas outras ferramentas podem não entender 'GO'. Algumas ferramentas interpretamGO
um pouco diferente. No SSMS, cada lote é executado na mesma sessão para que as transações possam abranger lotes, pelo menos algumas das ferramentas de linha de comando incluídas no SQL Server não mantêm a mesma sessão para cada lote em um arquivo, portanto, uma transação aberta será revertida quando GO é encontrado.GO foi bem abordado em outras respostas. Deixe-me adicionar alguns sobre ponto e vírgula:
Há muito tempo atrás, isso não era algo que usávamos. Mas o padrão SQL (ANSI/ISO SQL) especificava que uma instrução SQL deveria terminar com ponto e vírgula. Assim, em uma determinada versão, a MS permitiu que ela obedecesse ao ANSI SQL. Mas era, e principalmente ainda é, um no-op. Ou seja, não faz diferença se você tem ou não
Eu não estava envolvido quando a linguagem SQL foi inventada (eu era criança), mas posso imaginar que o ponto e vírgula foi especificado como um terminador de instrução para simplificar a análise do SQL. Ou seja, quando você envia SQL para o mecanismo db, ele primeiro precisa analisar (entender o que você disse, basicamente) a(s) instrução(ões). Você provavelmente pode imaginar que seria mais fácil para o código de análise no mecanismo se ele pudesse procurar algum caractere específico que significa "fim de instrução". Daí ponto e vírgula. Mas, como observei, o SQL Server não usava ponto e vírgula para análise.
Agora, com o tempo, alguns novos elementos de linguagem que foram introduzidos exigiram que a instrução anterior fosse terminada com ponto e vírgula (WITH como em CTE e THROW sendo dois exemplos). Sem ele, o SQL Server não conseguiu analisar (entenda o que você disse) e você obteve um erro gerado na fase de análise.
Ao mesmo tempo, o MS disse que não terminar uma declaração com ponto e vírgula era obsoleto. Ou seja, eles tentaram nos fazer acreditar que em algum momento (alguma versão futura), temos que terminar todas as nossas declarações com ponto e vírgula. Eu provavelmente não fui o único que achou isso um pouco divertido - imagine os aspectos de compatibilidade com versões anteriores! Pulando para o tempo presente, se você ler a documentação, descobrirá que esse não é mais o caso (na verdade, não há recursos obsoletos hoje - nenhum!).
Eu gostaria de acrescentar aqui que, se você adicionar a instrução Go entre instruções diferentes, ela continuará executando suas consultas, independentemente de qualquer erro lançado. Se você pular a instrução Go, sua execução será interrompida após qualquer erro e as próximas instruções não serão executadas. O melhor caso de uso, por exemplo, se você tiver várias instruções de inserção e quiser continuar sua execução se houver algum erro em sua instrução de inserção (você deseja apenas os logs de execução talvez), escreva este separador de lote. Se você deseja interromper a execução na instrução onde há um erro, deseja fazer algumas alterações e continuar a execução posteriormente, não escreva GO separator.