今天做代码审查时,看见以下一段触发器的创建脚本,我们一起来分析一下

create trigger [trigger_puClassRoomType]
on [dbo].[puClassRoomType]
AFTER update
as
declare @roomname nvarchar(100),@roomnumber nvarchar(100)
select @roomname = TypeName,@roomnumber=TypeNumber from Inserted
begin
update ExamingClasses set TypeName=@roomname where TypeNumber=@roomnumber
update PlanNumTimePlace set ClassroomName=@roomname where Classroomnum=@roomnumber
end
go

  书写这段代码的程序员可能对 1、SQLServer变量赋值 2、触发器Inserted表 这两个概念模糊,首先我们谈谈Inserted表,代码段中对Inserted表的查询方式没有带任何条件,似乎这张表只有单行一样,这明显是错误的。

  SQL Server为每个触发器创建了两个专业表:INSERTED表和DELETED表。这两个逻辑表,由系统来维护。用户不能对它们进行修改。它们存放在内存中而不是数据库中。这两个表的结构总与被该触发器作用的表的结构相同。触发器执行完成后,与该触发器相关的这两个表也被删除。

  • INSERTED表:存放由于执行INSERT或UPDATE语句而要向表中插入的所有行。在执行INSERT或UPDATE操作时,新的行同时添加到激活触发器的表和INSERTED表中,INSERTED表的内容是激活触发器的表中的新行的备份
  • DELETED表:存放由于执行DELETE或UPDATE语句而要从表中删除的所有行。在执行DELETE或UPDATE操作时,被删除的行从激活触发器的表中被移动到DELETED表,这两个表不会有共同的行。

  认识到INSERTED表的内容是根据更新条件来的,所以我觉得在使用INSERTED表的时候可以配合游标CURSOR来使用。同时提醒一下,以上代码段中读取INSERTED表的方式,将会返回INSERTED表的最后一行来进行赋值。

  SQL Server变量赋值的方式用两种,分别是SET和SELECT,代码段中选择了使用SELECT,而SQL Server推荐使用SET对变量进行赋值。虽然我们在日常工作中使用SELECT的场景比较多,两个赋值方式的概念也了比较解,但他们两者的区别我还是想再强调一下,当赋值失败时,SET和SELECT 的行为是不一样的。这里的赋值失败可能是没有数据或者数据类型不匹配等。此时SELECT会返回上一个值(如果上一个值已经赋值成功),而SET会把NULL赋值给变量。

  • 使用SET的情景:1、需要直接赋值,且不需要任何查询,比如变量初始化。2、故意赋予NULL值。3、为了将来的移植而遵循ANSI标准。4、赋予非标量值。
  • 使用SELECT的情景:1、直接赋予多值变量。2、通过查询来赋予变量(单值或多值均可)。3、减少代码量。4、为了获取变量如@@ROWCOUNT和@@ERROR的值。

SQL 使用触发器常见错误的更多相关文章

  1. 【oracle使用笔记1】SQL报的常见错误

    项目中使用最多的就是oracle数据库了,在实际的开发中书写SQL时遇到过许多错误,趁着现在不太忙,把之前遇到的总结一下,以后遇到的会持续更新总结. 1. ORA-00001:违反唯一约束条件 [原因 ...

  2. SQL Server 2008 常见异常收集(持续更新)

    写在前面: 最近,在使用SQL Server 2008时,出现了不少问题.发现,很多问题都是以前碰见过的,并且当时也寻找到了解决方法(绝大部分来源于“百度”与“Google”),只是时间一长,又忘记了 ...

  3. 配置sql server 2000以允许远程访问 及 连接中的四个最常见错误

    地址:http://www.cnblogs.com/JoshuaDreaming/archive/2010/12/01/1893242.html 配置sql server 2000以允许远程访问适合故 ...

  4. SQL Server 损坏修复 之一 常见错误解读

    SQL Server 对数据库损坏的错误类型做了细化,在此对几个典型的错误作一下介绍. 错误信息是:“在文件 '%ls'中.偏移量为 %#016I64x 的位置执行 %S_MSG 期间,操作系统已经向 ...

  5. 【常见的SQL Server连接失败错误以及解决方法】

    [常见的SQL Server连接失败错误以及解决方法] http://blog.csdn.net/feixianxxx/article/details/5523922 ADO连接SQL Server ...

  6. spring + myBatis 常见错误:SQL语法错误

    在程序运行时,有时候会出现如下错误: 这个错误通常是你的sqlmapper.xml中sql语句语法有错误.所以请仔细查看你sql语句是否正确,比如{#id}这样写就会报上述错误,其实应该#{id}这样 ...

  7. DB2常见错误

    +098 01568 动态SQL语句用分号结束+100 02000 没有找到满足SQL语句的行+110 01561 用DATA CAPTURE定义的表的更新操作不能发送到原来的子系统+111 0159 ...

  8. 喜忧参半的SQL Server触发器

    SQL Server触发器在非常有争议的主题.它们能以较低的成本提供便利,但经常被开发人员.DBA误用,导致性能瓶颈或维护性挑战. 本文简要回顾了触发器,并深入讨论了如何有效地使用触发器,以及何时触发 ...

  9. SQL性能优化常见措施(Lock wait timeout exceeded)

    SQL性能优化常见措施 目 录 1.mysql中explain命令使用 2.mysql中mysqldumpslow的使用 3.mysql中修改my.ini配置文件记录日志 4.mysql中如何加索引 ...

随机推荐

  1. 【mysql 统计分组之后统计录数条数】

    SELECT count(*) FROM 表名 WHERE 条件 // 这样查出来的是总记录条   SELECT count(*) FROM 表名 WHERE 条件 GROUP BY id //这样统 ...

  2. ApiDoc 一键生成注释

    本文来自网易云社区. 作者:盛国存 背景 我们日常在使用ApiDoc维护管理api文档,提高了api文档的整体维护性.但在老旧接口中,补充接口注解无疑是一次繁重的体力劳动.仔细查看,大多数接口的格式 ...

  3. [CentOS7] parted用于磁盘分区(同时支持GPT和MBR分区表)

    声明:本文主要总结自:鸟哥的Linux私房菜-第七章.Linux 磁碟與檔案系統管理,如有侵权,请通知博主 fdisk支持MBR分区表,gdisk支持GPT分区表,而parted支持两者 不知道为什么 ...

  4. 图片 响应式图像 Images Figures

    响应式图像 Bootstrap中的图像响应 .img-fluid <img class="img-fluid" src="http://lorempixel.com ...

  5. vue -- 打包资源正确引用及背景图引入

    一般情况下,通过webpack+vuecli默认打包的css.js等资源,路径都是绝对的. 但当部署到带有文件夹的项目中,这种绝对路径就会出现问题,因为把配置的static文件夹当成了根路径,那么要解 ...

  6. Unity Shader着色器优化

    https://mp.weixin.qq.com/s?__biz=MzU5MjQ1NTEwOA==&mid=2247493518&idx=1&sn=c51b92e9300bcf ...

  7. 关于Android模块化我有一些话不知当讲不当讲

    关于Android模块化我有一些话不知当讲不当讲 最近公司一个项目使用了模块化设计,本人参与其中的一个小模块开发,但是整体的设计并不是我架构设计的,开发半年有余,在此记录下来我的想法. 关于Andro ...

  8. H5页面开发的touchmove事件

    在做一屏滚动的H5页面的时候,必须移除touchmove事件,如果不移除,在安卓机上会触发微信原生的向下滚动拉出刷新.在IOS上出现上下都可以继续滑动,所以需要移除document的touchmove ...

  9. 前端 HTML-CSS 规范

    黄金定律 一个项目应该永远遵循同一套编码规范! 不管有多少人共同参与同一项目,一定要确保每一行代码都像是同一个人编写的. HTML 语法 用两个空格来代替制表符(tab) – 这是唯一能保证在所有环境 ...

  10. POJ1014 Dividing

    题目来源:http://poj.org/problem?id=1014 题目大意: Marsha和Bill拥有一些弹珠.但是这些弹珠的价值不一样.每个弹珠的价值都是1到6之间的自然数.他们希望把这些弹 ...