什么是"批次",为什么使用GO?

Pos*_*Guy 132 t-sql

我已阅读并阅读过MSDN等等.好的,它标志着一批的结束.

什么定义批次?当我粘贴一堆脚本同时运行时,我不明白为什么我需要去.

我从未理解过GO.任何人都可以更好地解释这个,当我需要使用它(在多少或什么类型的交易之后)?

例如,为什么每次更新后我都需要GO:

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

 GO

 UPDATE [Country]
   SET [CountryCode] = 'PT'
 WHERE code = 'PT'
Run Code Online (Sandbox Code Playgroud)

DVK*_*DVK 104

GO正确的TSQL命令.

相反,它是连接到SQL服务器的特定客户端程序的命令(Sybase或Microsoft - 不确定Oracle的作用),向客户端程序发出信号,告知客户端程序输入的命令集直到"go"需要被发送到要执行的服务器.

为什么/何时需要它?

  • GO SQL中的GO SQL服务器有一个"计数"参数 - 因此您可以将其用作"重复N次"快捷方式.

  • 极大的更新可能会填满SQL服务器的日志.为避免这种情况,可能需要将它们分成较小的批次go.

    在您的示例中,如果对一组国家/地区代码的更新具有超出日志空间的卷,则解决方案是将每个国家/地区代码分离为单独的事务 - 这可以通过在客户端上将它们分开来完成go.

  • 为了起作用,一些SQL语句必须由GO与以下语句分开.

    例如,您不能删除表并在单个事务中重新创建同名表,至少在Sybase中是这样(同样用于创建过程/触发器):

> 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
>
Run Code Online (Sandbox Code Playgroud)

  • "GO"不会"为您创建交易".如果您没有在显式事务中运行,则每个语句都会创建自己的事务.它是完全正交的.如果您想将更大的更新拆分为更小的步骤,您仍然可以在一个批处理中执行它,就像在常见的`WHILE @@ ROWCOUNT> 0`模式中一样. (6认同)
  • 正如稍后阅读此内容的任何人的澄清......"GO"与交易完全无关,并且使得关于事务和日志文件大小的第二点的答案不正确.`GO`将不起任何作用.第一个和第三个答案是正确的.此外,有时您需要将语句分成不同的批处理,例如,您无法在表中添加列,然后在同一批处理中使用该列.(继续) (4认同)
  • 此外,由于某些错误将中止批处理(某些错误仅中止语句),因此它也会在错误检测和恢复中发挥作用.某些陈述("创建视图"等)需要在他们自己的批次中. (4认同)
  • GO语句不会创建事务.如果您在一个BEGIN TRANSACTION语句中包含多个GO语句,并且最后您将执行ROLLBACK,它将回滚所有GO.如果在中间的一个GO中你会得到一些错误,最后你会做COMMIT,所有GO都会被提交.有点棘手. (3认同)
  • 如果你没有在显式事务中运行,那么`UPDATE T1 SET X = 2; UPDATE T1 SET X = 2;`将作为两个单独的事务*运行*无论如何*."GO"的加入完全没有区别.同样,如果你*在一个显式交易中运行它跨越批次并再次"GO"没有区别. (3认同)

Qua*_*noi 25

GO 它不是一个声明,它是一个批处理分隔符.

分隔的块由GO客户端发送到服务器进行处理,客户端等待其结果.

例如,如果你写

DELETE FROM a
DELETE FROM b
DELETE FROM c
Run Code Online (Sandbox Code Playgroud)

,这将作为单行3查询发送到服务器.

如果你写

DELETE FROM a
GO
DELETE FROM b
GO
DELETE FROM c
Run Code Online (Sandbox Code Playgroud)

,这将作为3一行查询发送到服务器.

GO本身不会去服务器(没有双关语意).它是一个纯粹的客户端保留字,只能通过SSMS和识别osql.

如果您将使用自定义查询工具通过连接发送它,则服务器甚至不会识别它并发出错误.

  • 你为什么要批量? (3认同)
  • 那么GO意味着发送它,然后不运行下一批,直到客户端收到"OK,批次完成并且成功"基本上是GO所做的,以便下一批可以成功运行并且客户端知道确保批处理在服务器端完成之前. (3认同)
  • @coffeeaddict:基本上,是的.此外,有些陈述需要在批次中首先出现(如`CREATE SCHEMA`); 其他要求是批量中的*only*语句(如`SET SHOWPLAN_XML ON`) (3认同)

gbn*_*gbn 19

许多命令需要在他们自己的批次中,如 CREATE PROCEDURE

或者,如果向表中添加列,则它应该在其自己的批处理中.如果您尝试在同一批次中选择新列,则会失败,因为在解析/编译时该列不存在.

SQL工具使用GO从一个脚本执行此操作:它不是SQL关键字,并且不被引擎识别.

这些是批次日常使用的2个具体例子.

编辑:在您的示例中,您不需要GO ...

编辑2,示例.您不能在一个批处理中删除,创建和权限...尤其是,存储过程的结束位置在哪里?

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
Run Code Online (Sandbox Code Playgroud)


Ste*_*eav 5

有时需要一遍又一遍地执行相同的命令或命令集。这可能是为了插入或更新测试数据,或者可能是为了性能测试而在服务器上施加负载。无论需要什么,最简单的方法就是设置一个 while 循环并执行代码,但在 SQL 2005 中,有一种更简单的方法可以做到这一点。

假设您要创建一个测试表并加载 1000 条记录。您可以发出以下命令,它会运行相同的命令 1000 次:

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

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

除此之外,它标记了 SQL 块的“结束”(例如在存储过程中)...这意味着您再次处于“干净”状态...例如:重置代码之前语句中使用的参数(不再定义)

  • @coffeeaddict:不。“批次”被一次性解析和编译。在编译时,dbo.TEST 不存在。你没有实例化一个对象,SQL 也不是逐行的程序代码 (2认同)