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 相关文章推荐
SQLServer2019 数据库环境搭建与使用的实现
Apr 08 SQL Server
sql字段解析器的实现示例
Jun 23 SQL Server
SQL Server中使用判断语句(IF ELSE/CASE WHEN )案例
Jul 07 SQL Server
SqlServer数据库远程连接案例教程
Jul 15 SQL Server
SQL写法--行行比较
Aug 23 SQL Server
SQLServer之常用函数总结详解
Aug 30 SQL Server
Spark SQL 2.4.8 操作 Dataframe的两种方式
Oct 16 SQL Server
SQL Server #{}可以防止SQL注入
May 11 SQL Server
SQL Server中使用表变量和临时表
May 20 SQL Server
SQL Server一个字符串拆分多行显示或者多行数据合并成一个字符串
May 25 SQL Server
SQL Server携程核心系统无感迁移到MySQL实战
Jun 01 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中使用array_filter()函数过滤空数组的实现代码
2014/08/19 PHP
php数组添加与删除单元的常用函数实例分析
2015/02/16 PHP
jQuery向下滚动即时加载内容实现的瀑布流效果
2016/01/07 PHP
js 数组克隆方法 小结
2010/03/20 Javascript
js导出格式化的excel 实例方法
2013/07/17 Javascript
javascript实现复制与粘贴操作实例
2014/10/16 Javascript
JQuery实现防止退格键返回的方法
2015/02/12 Javascript
JavaScript实现基于Cookie的存储类实例
2015/04/10 Javascript
JavaScript数组对象赋值用法实例
2015/08/04 Javascript
jQuery实现的fixedMenu下拉菜单效果代码
2015/08/24 Javascript
js实现接收表单的值并将值拼在表单action后面的方法
2015/11/23 Javascript
JavaScript 经典实例日常收集整理(常用经典)
2016/03/30 Javascript
针对BootStrap中tabs控件的美化和完善(推荐)
2016/07/06 Javascript
微信小程序 在线支付功能的实现
2017/03/14 Javascript
基于vue2.x的电商图片放大镜插件的使用
2018/01/22 Javascript
jQuery选择器之基本选择器用法实例分析
2019/02/19 jQuery
浅谈layui使用模板引擎动态渲染元素要注意的问题
2019/09/14 Javascript
微信sdk实现禁止微信分享(使用原生php实现)
2019/11/15 Javascript
如何优雅地在Node应用中进行错误异常处理
2019/11/25 Javascript
使用Bootstrap做一个朝代历史表
2019/12/10 Javascript
vue实现淘宝购物车功能
2020/04/20 Javascript
如何管理Vue中的缓存页面
2021/02/06 Vue.js
[01:15:56]2018DOTA2亚洲邀请赛3月30日 小组赛A组 TNC VS Newbee
2018/03/31 DOTA
使用Python中的tkinter模块作图的方法
2017/02/07 Python
ubuntu 18.04搭建python环境(pycharm+anaconda)
2019/06/14 Python
Python学习笔记之For循环用法详解
2019/08/14 Python
Python3实现配置文件差异对比脚本
2019/11/18 Python
深入浅析python的第三方库pandas
2020/02/13 Python
Jmeter HTTPS接口测试证书导入过程图解
2020/07/22 Python
python批量修改文件名的示例
2020/09/27 Python
C,C++的几个面试题小集
2013/07/13 面试题
户籍证明的格式
2014/01/13 职场文书
2015年党建工作汇报材料
2015/06/25 职场文书
会议承办单位欢迎词
2015/09/30 职场文书
详解CSS故障艺术
2021/05/25 HTML / CSS
python开发制作好看的时钟效果
2022/05/02 Python