自己的理解:用GO隔开,就相当于在不同的查询窗口里执行SQL,GO需要单独提交事务的
整理时参考博文:
http://www.cnblogs.com/kissdodog/p/3163880.html
http://lockrock.blog.51cto.com/2147255/775783
批处理是作为一个逻辑单元的T-SQL语句。完整的批处理当中,如果第一条语句不能通过语法分析,那么不会运行任何语句。语句会顺序执行,如果执行过程中发现一条语句存在错误,那么会在运行时报错,但在产生错误的语句之前,没有语法错误的语句都已经运行了。
为了将一个脚本分为多个批处理,可使用GO语句:
GO语句必须自成一行,只有注释可以在同一行上;
USE [AdventureWorks2008R2] SELECT * FROM Person.Person WHERE BusinessEntityID = 20 GO
这种情况是会报错的。
被GO语句隔开的所有SQL语句会被编译成一个执行计划并发送到服务器,与任何其他批处理无关,每个批处理单独发送到服务器,这样在执行的过程中,因为每个批处理被单独地处理,所以一个批处理中的错误不会阻止另一个批处理运行;
SELECT 1/0 GO SELECT 0/1
这种情况就第一句会报错,第二句则正常返回结果,如果这些批处理之间存在依赖性,那么错误发生之后的每个批处理都会失败。依赖性指的是后面的语句,依赖前面执行的结果或变量等等。
一个常见的错误是认为GO是T-SQL命令,其实GO是一个只能被编辑工具(Management Studio),sqlcmd识别的命令。当编辑工具遇到GO语句时,会将GO语句看做一个终止批处理的标记,将其打包,并且作为一个独立的单元发送到服务器,不包括GO。因为服务器本身根本不知道GO是什么意思。所以如果基于 ODBC 或 OLE DB API 的应用程序试图执行 GO 命令,会收到语法错误;因为SQL Server 实用工具从不向服务器发送 GO 命令。
权限:GO 是一个不需任何权限的实用工具命令,可以由任何用户执行。
案例:
BEGIN TRUNCATE TABLE [TABLETEST]
GO END
包裹在其中的语句是表示一个完整的批处理,此时用GO隔开是会报错的。
使用GO的时候也必须遵照使用批处理的规则:
例如,在同一批处理中,创建数据库之后不能直接使用其新建的数据库。
CREATE DATABASE Test USE Test
这样分析是不会通过的,执行的时候一句也不会被执行,但是在两句之间加入GO之后,虽然分析还是会报错,但实际执行是可以正常执行的;如果不加入GO,则是会直接提示数据库不存在。
另外一个比较重要的规则是局部(用户定义)变量的作用域限制在一个批处理中,不可在 GO 命令后引用。
使用方法补充:GO [count] count 为正整数,指定GO 之前的批处理执行指定的次数:
Insert [Roc] Select 'aking' GO 10
表示批处理执行10次,向表Roc中插入10行记录aking。
关于批处理
批处理中的错误分为以下两类:1、语法错误2、运行时错误
语法错误,一般在执行前使用分析就可以查出:如果查询分析器发现一个语法错误,那么批处理的处理过程会被立即取消。因为语法检查发生在批处理编译或者执行之前,所以在语法检查期间的一个失败意味着还没有批处理被执行-不管语法错误发生在批处理中的什么位置;
运行时错误的工作方式有很大不同,这种情况分析是不会报错的,只有在运行的过程中遇到错误才会终止,因为任何在遇到运行时错误之前执行的语句已经完成了,所以除非是未提交事务的一部分,否则这些语句所做的任何事情都已经是现实了。
一般而言,运行时错误将终止从错误发生的地方到此批处理末端的批处理的执行。下一个批处理不影响。