SQL Server使用T-SQL语句批处理


Posted in SQL Server onMay 20, 2022

批处理简介

批处理是作为一个逻辑单元的T-SQL语句。如果一条语句不能通过语法分析,那么不会运行任何语句。如果一条语句在运行时失败,那么产生错误的语句之前的语句都已经运行了。

为了将一个脚本分为多个批处理,可使用GO语句。

GO语句的特点:

  • GO语句必须自成一行,只有注释可以再同一行上。
  • 它使得自脚本的开始部分或者最近一个GO语句以后的所有语句编译成一个执行计划并发送到服务器,与任何其他批处理无关。
  • GO语句不是T-SQL命令,而是由各种SQL Server命令实用程序(如:Management Studio中的"查询"窗口)识别的命令。

1、自成一行

GO命令应当自成一行。在技术上,可以在GO命令之后的同一行开始一个新的批处理,但是这会严重影响可读性。T-SQL语句不能放在GO语句之前,否则GO语句经常会被错误地理解,从而造成语法分析错误或产生一些不可预料的后果。例如,在WHERE子句之后使用一个GO语句。

SELECT * FROM Person WHERE Id = 100 GO

分析器就不知道如何处理。

消息 102,级别 15,状态 1,第 1 行
  'GO' 附近有语法错误。

2、每个批处理单独发送到服务器

因为每个批处理被单独地处理,所以一个批处理中的错误不会阻止另一个批处理运行。要说明这点,请看一下下面的代码。

SELECT 1/0
  GO
  SELECT 0/1

如果这些批处理之间没有任何依赖性,则每个批处理在运行时是完全自治的。

消息 8134,级别 16,状态 1,第 1 行
  遇到以零作除数错误。

  (1 行受影响)

如果这些批处理之间存在依赖性,那么错误发生之后的每个批处理都会失败。依赖性指的是后面的语句,依赖前面执行的结果或变量等等。  

3、GO不是T-SQL命令

一个常见的错误是认为GO是T-SQL命令,其实GO是一个只能被编辑工具(Management Studio)识别的命令。

当编辑工具遇到GO语句时,会将GO语句看做一个终止批处理的标记,将其打包,并且作为一个独立的单元发送到服务器,不包括GO。因为服务器本身根本不知道GO是什么意思。

批处理中错误

批处理中的错误分为以下两类:

  • 语法错误
  • 运行时错误

如果查询分析器发现一个语法错误,那么批处理的处理过程会被立即取消。因为语法检查发生在批处理编译或者执行之前,所以在语法检查期间的一个失败意味着还没有批处理被执行-不管语法错误发生在批处理中的什么位置。

运行时错误的工作方式有很大不同,因为任何在遇到运行时错误之前执行的语句已经完成了,所以除非是未提交事务的一部分,否则这些语句所做的任何事情都已经是现实了。

一般而言,运行时错误将终止从错误发生的地方到此批处理末端的批处理的执行。下一个批处理不影响。

何时使用批处理

使用批处理有若干个理由,但是所有的批处理都有一个共同点-当脚本中的一些事情必须发生在另外一件事情之前或者分开发生时,需要使用批处理。

1.要求有自己的批处理的语句

有一些命令必须有他们自己的批处理。

  • CREATE DEFAULT
  • CREATE PROCEDURE
  • CREATE RULE
  • CREATE TRIGGER
  • CREATE VIEW

如果想在单个脚本中将这些语句中的任意一个和其他语句进行组合,那么需要通过使用GO语句将他们分散到各自的批处理中。

2、使用批处理建立优先权

当需要建立优先权时,就可能用到批处理。也就是说,在下一个任务开始之前,需要全部完成上一个任务。在大多数时候,SQL Server可以很好地处理这种情况 - 脚本中的第一条语句是首先执行的,并且脚本中的第二条语句可以依赖第二条语句运行时服务器所处的适当状态。

下面来看一个例子:

USE master

  CREATE DATABASE Test

  CREATE TABLE TestTable
  (
      col1 int,
      col2 int
  )

当执行上面的脚本,提示命令已成功完成。但是真的没问题吗?

当查看Test数据库时,发现表TestTable并不存在,反而master数据库里多了一个TestTable表。

为什么表被创建在了master数据库中,答案取决于当运行CREATE TABLE语句时,当前数据库是什么。在这个例子中,它恰好是master数据库,所以表就创建在该数据库中。

你可能以为将上述代码改成这样可能就能够解决:

CREATE DATABASE Test

  USE Test

  CREATE TABLE TestTable
  (
      col1 int,
      col2 int
  )

但很遗憾,并不能,错误信息如下:

消息 911,级别 16,状态 1,第 3 行
  数据库 'Test' 不存在。请确保正确地输入了该名称。

分析器尝试验证代码时,发现USE引用一个不存在的数据库,这是批处理语句不可或缺,正确的代码如下:

CREATE DATABASE Test
  GO  --此GO是两主角
  USE Test

  CREATE TABLE TestTable
  (
      col1 int,
      col2 int
  )

就这样加了一个GO之后,问题成功解决。

下面再来看一个例子:

USE Test
  ALTER TABLE TestTable
      ADD col3 int
  INSERT INTO TestTable
      (col1,col2,col3)
  VALUES
      (1,1,1)

以上代码在查询分析器中提示col3列不存在。实际上,以上代码也可以通过一个GO解决。

USE Test
  ALTER TABLE TestTable
      ADD col3 int
  GO  --先更改数据库,然发送插入,此时就是分开进行语法验证了
  INSERT INTO TestTable
      (col1,col2,col3)
  VALUES
      (1,1,1)

到此这篇关于SQL Server批处理T-SQL语句的文章就介绍到这了。


Tags in this post...

SQL Server 相关文章推荐
SQL Server数据定义——模式与基本表操作
Apr 05 SQL Server
SqlServer: 如何更改表的文件组?(进而改变存储位置)
Apr 05 SQL Server
SQL SERVER中常用日期函数的具体使用
Apr 08 SQL Server
SQLServer 错误: 15404,无法获取有关 Windows NT 组/用户 WIN-8IVSNAQS8T7\Administrator 的信息
Jun 30 SQL Server
SQL写法--行行比较
Aug 23 SQL Server
SQLServer之常用函数总结详解
Aug 30 SQL Server
sql server 累计求和实现代码
Feb 28 SQL Server
SQL Server数据库基本概念、组成、常用对象与约束
Mar 20 SQL Server
Sql Server 行数据的某列值想作为字段列显示的方法
Apr 20 SQL Server
使用 MybatisPlus 连接 SqlServer 数据库解决 OFFSET 分页问题
Apr 22 SQL Server
SQL Server数据库备份和恢复数据库的全过程
Jun 14 SQL Server
在SQL Server中使用 Try Catch 处理异常的示例详解
Jul 15 SQL Server
SQL Server 中的事务介绍
May 20 #SQL Server
SQL Server中锁的用法
May 20 #SQL Server
SQL Server中使用表变量和临时表
May 20 #SQL Server
SQL Server中的游标介绍
May 20 #SQL Server
SQL Server #{}可以防止SQL注入
May 11 #SQL Server
SQL Server 忘记密码以及重新添加新账号
使用 MybatisPlus 连接 SqlServer 数据库解决 OFFSET 分页问题
Apr 22 #SQL Server
You might like
php Sql Server连接失败问题及解决办法
2009/08/07 PHP
PHP学习笔记之二 php入门知识
2011/01/12 PHP
PHP 小心urldecode引发的SQL注入漏洞
2011/10/27 PHP
thinkphp实现发送邮件密码找回功能实例
2014/12/01 PHP
Joomla实现组件中弹出一个模式(modal)窗口的方法
2016/05/04 PHP
基于Jquery的温度计动画效果
2010/06/18 Javascript
刷新页面的几种方法小结(JS,ASP.NET)
2014/01/07 Javascript
深入理解JavaScript的React框架的原理
2015/07/02 Javascript
javaScript实现滚动新闻的方法
2015/07/30 Javascript
实例详解jQuery结合GridView控件的使用方法
2016/01/04 Javascript
jQuery图片切换动画效果
2017/02/28 Javascript
JS switch判断 三目运算 while 及 属性操作代码
2017/09/03 Javascript
详解vue开发中调用微信jssdk的问题
2019/04/16 Javascript
layui 根据后台数据动态创建下拉框并同时默认选中的实例
2019/09/02 Javascript
vue实现表格过滤功能
2019/09/27 Javascript
基于PHP pthreads实现多线程代码实例
2020/06/24 Javascript
javascript使用canvas实现饼状图效果
2020/09/08 Javascript
JavaScript中展开运算符及应用的实例代码
2021/01/14 Javascript
Python获取文件ssdeep值的方法
2014/10/05 Python
python通过floor函数舍弃小数位的方法
2015/03/17 Python
树莓派使用python-librtmp实现rtmp推流h264的方法
2019/07/22 Python
Python利用逻辑回归模型解决MNIST手写数字识别问题详解
2020/01/14 Python
基于django 的orm中非主键自增的实现方式
2020/05/18 Python
Python参数传递及收集机制原理解析
2020/06/05 Python
matplotlib交互式数据光标实现(mplcursors)
2021/01/13 Python
详解CSS3中的box-sizing(content-box与border-box)
2019/04/19 HTML / CSS
使用phonegap进行提示操作的具体方法
2017/03/30 HTML / CSS
主题教育活动总结
2014/05/05 职场文书
2015高三毕业寄语赠言
2015/02/27 职场文书
安全教育第一课观后感
2015/06/17 职场文书
2016年综治和平安建设宣传月活动总结
2016/04/01 职场文书
话题作文之关于呼唤
2019/11/29 职场文书
python 算法题——快乐数的多种解法
2021/05/27 Python
新手入门Jvm-- JVM对象创建与内存分配机制
2021/06/18 Java/Android
gtx1650怎么样 gtx1650显卡相当于什么级别
2022/04/08 数码科技
SQL试题 使用窗口函数选出连续3天登录的用户
2022/04/24 Oracle