2010-04-19 33 views
125

He leído y leído MSDN, etc. Ok, entonces señala el final de un lote.¿Qué es un "lote" y por qué se usa GO?

¿Qué define un lote? No veo por qué necesito ir cuando estoy pegando en un conjunto de scripts para ejecutarlos todos al mismo tiempo.

Nunca he entendido GO. ¿Alguien puede explicar esto mejor y cuándo debo usarlo (después de cuántas o qué tipo de transacciones)?

Por ejemplo ¿por qué necesitaría ir después de cada actualización aquí:

UPDATE [Country] 
    SET [CountryCode] = 'IL' 
WHERE code = 'IL' 

GO 

UPDATE [Country] 
    SET [CountryCode] = 'PT' 
WHERE code = 'PT' 
+1

posible duplicado de (http: // stackoverflow.com/questions/2299249/what-is-the-use-of-go-in-sql-server-management-studio) – tvanfosson

Respuesta

101

GO es no correctamente un comando TSQL.

sino que es un comando para el programa cliente específico que se conecta a un servidor SQL (Sybase o Microsoft de - no está seguro de lo que hace Oracle), lo que indica que el programa cliente de que el conjunto de comandos que eran de entrada en ella hasta hasta que el "ir" necesite ser enviado al servidor para ser ejecutado.

¿Por qué/cuándo lo necesita?

  • GO en MS SQL Server tiene un parámetro de "recuento" - para que pueda utilizarlo como un acceso directo "repetir N veces".

  • Las actualizaciones extremadamente grandes pueden llenar el registro del servidor SQL. Para evitar eso, pueden necesitar separarse en lotes más pequeños a través del go.

    En su ejemplo, si la actualización de un conjunto de códigos de país tiene tal volumen que se quedará sin espacio de registro, la solución es separar cada código de país en una transacción separada, lo que se puede hacer separándolos el cliente con go.

  • Algunas sentencias de SQL DEBEN estar separadas por GO de las siguientes para que funcionen.

    Por ejemplo, no se puede eliminar una tabla y volver a crear el mismo nombre tabla en una sola transacción, por lo menos en Sybase (ídem para la creación de procedimientos/disparadores):

> drop table tempdb.guest.x1   
> create table tempdb.guest.x1 (a int) 
> go 
    Msg 2714, Level 16, State 1 
    Server 'SYBDEV', Line 2 
    There is already an object named 'x1' in the database. 

> drop table tempdb.guest.x1   
> go 
> create table tempdb.guest.x1 (a int) 
> go 
> 
+0

CREATE TABLE no necesita ser separado ... ¿cómo se crearía una tabla temporal en un proceso almacenado, por ejemplo? – gbn

+0

@gbn - tienes razón ... intentaré recordar qué operaciones deben separarse en su propia transacción y actualizar la Q cuando lo haga. – DVK

+3

La instrucción GO no crea transacción. Si incluye múltiples declaraciones GO en una instrucción BEGIN TRANSACTION y al final hará un ROLLBACK, revertirá todas las GO. Y si en una IR en el medio Obtendrá algún error, y al final lo hará COMPROMETER, todo GO sin error será cometido. Es un poco complicado. –

4

A veces hay una necesidad de ejecutar el mismo comando o conjunto de comandos una y otra vez. Esto puede ser para insertar o actualizar los datos de prueba o puede ser una carga para su servidor para las pruebas de rendimiento. Cualquiera sea la necesidad, la manera más fácil de hacerlo es configurar un bucle while y ejecutar su código, pero en SQL 2005 hay una manera aún más fácil de hacerlo.

Digamos que desea crear una tabla de prueba y cargarla con 1000 registros. Se podría emitir el comando siguiente y se ejecutará el mismo comando 1000 veces:

CREATE TABLE dbo.TEST (ID INT IDENTITY (1,1), ROWID uniqueidentifier) 
GO 
INSERT INTO dbo.TEST (ROWID) VALUES (NEWID()) 
GO 1000 

fuente: http://www.mssqltips.com/tip.asp?tip=1216

Aparte de eso, marca el "fin" de un bloque de SQL (por ejemplo, en un procedimiento almacenado) ... lo que significa que está en un estado "limpio" de nuevo ... ej: Parámetros utilizados en la declaración antes del código se ponen a cero (no definido ya)

+0

Bien, entonces ¿por qué necesitas IR. ¿Para que sepa que la tabla se creó antes de ejecutar la instrucción de inserción? Todavía no lo entiendo – PositiveGuy

+0

Vea La forma en que pienso sobre esto, es que si no tengo GO en su ejemplo, primero se crea la tabla, está allí ahora, por lo que la inserción debería funcionar. No entiendo para qué sirve GO si creé la tabla ... está disponible para la próxima inserción, ¿no?!?!?! – PositiveGuy

+2

@coffeeaddict: no. el "lote" se analiza y se compila de una vez. En tiempo de compilación, dbo.TEST no existe. No estás instanciando un objeto y SQL no es código de procedimiento línea por línea – gbn

19

Muchos necesidad de comandos para estar en su propio lote, como CREATE PROCEDURE

O, si se agrega una columna a una tabla, entonces debería ser en su propio lote. Si intentas SELECCIONAR la nueva columna en el mismo lote, falla porque en el momento de compilar/compilar la columna no existe.

GO utiliza las herramientas SQL para resolver esto desde un script: no es una palabra clave SQL y el motor no lo reconoce.

Estos son 2 ejemplos concretos del uso diario de lotes.

Editar: En tu ejemplo, no es necesario ir ...

Editar 2, ejemplo. No puede soltar, crear y autorizar en un lote ... no menos importante, ¿dónde está el final del procedimiento almacenado?

IF OBJECT_ID ('dbo.uspDoStuff') IS NOT NULL 
    DROP PROCEDURE dbo.uspDoStuff 
GO 
CREATE PROCEDURE dbo.uspDoStuff 
AS 
SELECT Something From ATable 
GO 
GRANT EXECUTE ON dbo.uspDoStuff TO RoleSomeOne 
GO 
24

GO no es una declaración, es un separador de lotes.

Los bloques separados por GO son enviados por el cliente al servidor para su procesamiento y el cliente espera por sus resultados.

Por ejemplo, si se escribe

DELETE FROM a 
DELETE FROM b 
DELETE FROM c 

, éste se enviará al servidor como una sola 3 -line consulta.

Si se escribe

DELETE FROM a 
GO 
DELETE FROM b 
GO 
DELETE FROM c 

, éste se enviará al servidor como 3 consultas de una sola línea.

GO no va al servidor (sin juego de palabras). Es una palabra reservada pura del lado del cliente y solo es reconocida por SSMS y osql.

Si va a usar una herramienta de consulta personalizada para enviarla a través de la conexión, el servidor ni siquiera la reconocerá y emitirá un error.

+2

¿Por qué tienes que hacer un lote en absoluto? – PositiveGuy

+3

Entonces GO significa enviarlo y luego no ejecutar el siguiente lote hasta que el cliente reciba "OK, ese lote está hecho y fue exitoso" básicamente es lo que hace el GO para que el siguiente lote pueda ejecutarse con éxito y el cliente sabe seguro el lote antes de que se haga en el lado del servidor. – PositiveGuy

+3

@coffeeaddict: básicamente, sí. Además, algunas declaraciones requieren ser las primeras en sus lotes (como 'CREATE SCHEMA'); otros requieren ser las * únicas * declaraciones en sus lotes (como 'SET SHOWPLAN_XML ON ') – Quassnoi

3

Como todos ya han dicho, "IR" no es parte de T-SQL. "IR" es un separador de lotes en SSMS, una aplicación cliente utilizada para enviar consultas a la base de datos. Esto significa que las variables declaradas y las variables de tabla no persistirán desde el código antes del "IR" al código que lo sigue.

De hecho, GO es simplemente la palabra predeterminada utilizada por SSMS. Esto se puede cambiar en las opciones si lo desea. Por un poco de diversión, cambie la opción en el sistema de otra persona para usar "SELECCIONAR" como un separador por lotes en lugar de "IR". Perdona mi risa cruel.

+1

Aquí hay un punto realmente serio que debe hacerse: debe tratar GO como si fuera una palabra clave aunque no lo sea. Usted tampoco debería cambiarlo. Los errores causados ​​por la reutilización de identificadores especiales pueden ser muy difíciles de depurar. –

+0

@The Dixie Flatline: ¿está seguro de que las variables declaradas no persisten? En MSSQL 2016 aparece el error "variable ya declarada" al ejecutar: declare $ test int; establecer $ test = 5; seleccione $ test go; declarar $ test int; - Reemplazar $ con , no puede usar múltiples en los comentarios de SE. – Wouter

0

Se usa para dividir bloques lógicos. Su código se interpreta en la línea de comandos sql y esto indica el siguiente bloque de código.

Pero podría usarse como declaración recursiva con un número específico.

Probar:

exec sp_who2 
go 2 

Algunos declaración tiene que estar delimitado por GO: [? ¿Cuál es el uso de GO en SQL Server Management Studio]

use DB 
create view thisViewCreationWillFail