在SQL Server中使用GO关键字

6
我知道GO关键字的用法。它将多个语句作为整个组一起发送到SQL服务器,而不是逐个发送每个语句。我希望我的理解是正确的!
但我想知道程序员在实际应用中是否使用它。比如,如果我们创建一个存储过程,那么它也会做同样的事情,它也会编译代码并生成执行计划,并将整个组发送到服务器。
所以,在数据库对象(如触发器、视图、存储过程)的编码中,我们需要指定GO关键字吗?
7个回答

14

GO 命令用于标记批处理的结束。需要注意的是,它不是 T-SQL 语句。

Batch(批处理) 是由一个或多个 Transact-SQL 语句组成的一组命令,从应用程序发送到 SQL Server 同时进行执行。

在 SQL Server 中,GO非常有用,但你只需要在确实需要时使用它。 因此,你需要记住,使用 GO 命令定义批处理时,你还需要定义该特定 T-SQL 代码的作用域。在批处理中定义的局部变量仅适用于该批处理。

作用域示例 -

DECLARE @STRING1 AS VARCHAR(50)
DECLARE @STRING2 AS VARCHAR(50)

SET @STRING1='BATCH 2'
SET @STRING2='BATCH 3'

SELECT @STRING1 AS RESULT
GO

SELECT @STRING2 AS RESULT
GO

运行此代码将会产生错误,提示@STRING2未声明。因为该变量的作用范围随着GO语句的结束而结束。因此,在使用GO语句时要小心并明智地使用。

来源 - http://aartemiou.blogspot.com/2009/08/using-go-command-in-sql-server.html


@sqlchild - 这是一个根据您应用程序中的触发器、视图和存储过程的类型而需要做出的逻辑决策。 - Sachin Shanbhag
3
另外需要注意的是,如果你在编写程序时使用 ADODB 或 OleDB 来运行查询,使用 GO 语句会生成错误。这是一个专门用于 Query Analyzer/SQL Server Management Studio 的关键字。对于 SSMS,可以在“工具”菜单中找到“选项”来进行配置。在“查询执行”->“SQL Server”->“常规”下的“批处理分隔符”设置中包含了 GO 关键字。 - jveazey

7
GO 关键字表示 SQL Server Management Studio 执行批处理的结束 - 通常情况下,SQL Server Management Studio 在一个批处理中执行所有语句(可以将批处理视为到数据库的往返),但在某些情况下可能需要在不同的批处理中执行语句(例如,SET SHOWPLAN_ALL 语句必须是批处理中唯一的语句)。
例如,在 SQL Server Management Studio 中执行以下脚本:
USE StackOverflow
GO
SELECT * FROM Comments

在C#中,大致相当于执行以下操作:

using (var cmd = new SqlCommand("USE StackOverflow", conn))
{
    cmd.ExecuteReader();
}
using (var cmd = new SqlCommand("SELECT * FROM Comments", conn))
{
    cmd.ExecuteReader();
}    

请注意,GO 不是 T-SQL 关键字,它只能被 SQL Server Management Studio 和其他 SQL 工具理解。例如,以下内容将无法正常工作,并导致运行时异常:
string cmdText = @"
USE StackOverflow
GO
SELECT * FROM Comments";

using (var cmd = new SqlCommand(cmdText, conn))
{
    cmd.ExecuteReader();
}

4

GO不是SQL中的关键字,而是SSMS和其他工具将较大脚本分成批处理的指令。


4

除了脚本,您实际上无法在存储过程、触发器、视图、UDF甚至动态SQL中使用GO。这是仅用于脚本的。


1

MSDN 定义Go为:

向 SQL Server 实用程序发出一批 Transact-SQL 语句结束的信号。

并进一步说明:

GO 不是 Transact-SQL 语句,而是 sqlcmd 和 osql 实用程序以及 SQL Server Management Studio 代码编辑器识别的命令。

SQL Server 实用程序将 GO 解释为一个信号,表示它们应该将当前批次的 Transact-SQL 语句发送到 SQL Server 的实例。当前批次的语句由自上一个 GO 或自临时会话或脚本启动以来输入的所有语句组成(如果这是第一个 GO,则为自脚本启动)。

我最常使用 GO 的时间是在对象创建脚本中。

我的创建脚本通常遵循以下模式:

USE SomeDatabase
GO

If Exists(SELECT * FROM ...)
 DROP

CREATE PROC as foo
BEGIN
END
GO 

Grant exec on Foo to Bar

所以这两个GO非常重要,因为我想确保我在正确的数据库上运行,并且如果没有GO,它将无法工作。第二个GO非常重要,否则存储过程将尝试将授权语句作为过程的一部分运行。


1

我怀疑最好使用分号 (;) 分隔语句。


这不相关。GO是批处理分隔符。分号是语句分隔符。您可以在一个批处理中有多个语句。顺便说一下,您甚至不需要使用单词“GO”。在SSMS选项中默认设置了GO。理论上,如果您想要的话,可以将其设置为其他单词。如果您真的很邪恶(@rob_farley),并且同事离开了他们的屏幕未锁定,您可以将其设置为“SELECT”,然后观察当他们回来并开始编码时混乱和错误消息的出现。每次SSMS看到单词SELECT时,它都会认为“嘿,这是批处理的结尾!” - DatumPoint

1

在SQL Server中,不需要指定GO指令。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接