Separação de Lotes com o comando "GO"
Autor: Jaxmim | Publicado: 2009-10-28T07:22:00-07:00

Esta semana me perguntaram: "Renata, para que serve o comando 'GO' ao final de uma query?". Titubiei e não consegui responder. Apenas disse: "É uma forma de comitar instruções que modificam estrutura do banco. Semelhante ao Commit que escreve o registro no arquivo de dados".Diante dessa resposta mal dada, resolvi procurar pelo site do MSDN.Sintaxe: GO [count]Sinaliza o término de um lote de instruções Transact-SQL para os utilitários SQL Server. O count define quantas vezes o lote acima do 'GO' deve ser executado.Num exemplo, se executo uma query para criação de uma View e antes existe alguma outra instrução como um 'USE [Banco]', sei que a solução é colocar um 'GO' antes do 'Create View':Tentativa 1 - Um único lote para escolha do banco de dados, criação da view e select na viewComando:USE B_BANCOCREATE VIEW V_VIEW AS SELECT * FROM T_TABELASELECT * FROM V_VIEWResultado:Msg 111, Level 15, State 1, Line 3'CREATE VIEW' must be the first statement in a query batch.Tentativa 2 - Adicionei ';' para tentar separar os comandoComando:USE B_BANCO;CREATE VIEW V_VIEW AS SELECT * FROM T_TABELA;SELECT * FROM V_VIEW;Resultado:Msg 111, Level 15, State 1, Line 3'CREATE VIEW' must be the first statement in a query batch.Tentativa 3 - Inclusão do comando 'GO' para separar a query em dois lotesComando:USE B_BANCO;GOCREATE VIEW V_VIEW AS SELECT * FROM T_TABELA;SELECT * FROM V_VIEW;Resultado:Msg 170, Level 15, State 1, Procedure V_VIEW, Line 2Line 2: Incorrect syntax near ';'.Tentativa 4 - Já conectada em B_BANCO, retirei o ';' e incluí  'GO' após o create view, criando assim três lotesComando:USE B_BANCO;GOCREATE VIEW V_VIEW AS SELECT * FROM T_TABELA;GOSELECT * FROM V_VIEW;Resultado:SQ_DET_CLD  PC_VR----------- ---------------------------------------1           2.002           2.004           2.005           2.006           2.008           43.009           2.00(7 row(s) affected)Explicação:- Na tentativa 1, temos três instruções relacionadas e dependentes, por este motivo se encontram na mesma query. Porém, segundo o MSDN, Para CREATE DEFAULT, CREATE FUNCTION, CREATE PROCEDURE, CREATE RULE, CREATE SCHEMA, CREATE TRIGGER e CREATE VIEW não se pode combiná-los com outras instruções em um mesmo lote.- Na tentativa 2, temos as mesmas instruções separadas por ponto e vírgula que é uma convenção usada na linguagem SQL que em Transact-SQL não é obrigatória, porém também não é errada. Mas em alguns comandos próprios da T-SQL não podem ser usados.- Na tentativa 3, usando 'GO' depois do comando 'USE', o bloco de código foi separado entre dois lotes. Desta forma, o banco B_BANCO foi posicionado, porém a view não foi criada por haver ";" ao final do comando Create View.- Já na tentativa 4, a retirada do ';' e a inclusão do 'GO' ao final do comando 'Create View', separou a transação em três lotes possibilitando a criação da view e exibição do resultado pelo comando Select ao final.Apenas por curiosidade, tentei uma quinta tentativa:Tentativa 5 - Retirada do 'GO' após o 'USE'Comando:USE B_BANCOCREATE VIEW V_VIEW AS SELECT * FROM T_TABELAGOSELECT * FROM V_VIEWResultado:Msg 111, Level 15, State 1, Line 4'CREATE VIEW' must be the first statement in a query batch.Msg 208, Level 16, State 1, Line 1Invalid object name 'V_VIEW'.Explicação:Foram retornadas duas mensagens de erro pois existe aí dois lotes. O primeiro lote retorna erro pois conforme falado, 'CREATE VIEW' deve ser a primeira instrução de um lote. O segundo lote, do 'Select', é compilado, mas por não existir a View ainda, retorna erro.Sobre o uso de um número como argumento count de 'GO':Comando:USE B_BANCOGOCREATE TABLE T_TABELA (texto char(5))GOINSERT INTO T_TABELA VALUES ('teste')GO 4SELECT * FROM T_TABELAResultado:Beginning execution loop(1 row(s) affected)(1 row(s) affected)(1 row(s) affected)(1 row(s) affected)Batch execution completed 4 times.texto-----------testetestetesteteste(4 row(s) affected)Referência: http://msdn.microsoft.com/pt-br/library/ms175502.aspxMais uma pro caderninho!