SQL Server 触发器实例

楼主
我是社区第238588位番薯,欢迎点我头像关注我哦~
1. 概述1.1 触发器简介
  • 触发器( trigger )是 SQL server 提供给程序员和数据分析员用来保证数据完整性的一种方法,它是与表事件相关的特殊的存储过程,它的执行不是由程序调用,也不是手工启动,而是由事件来触发,例如当对一个表进行操作( insert,delete, update)时就会激活它执行,触发器经常用于加强数据的完整性约束和业务规则等。

  • 触发器可以查询其他表,而且可以包含复杂的 SQL 语句。它们主要用于强制服从复杂的业务规则或要求。

  • 触发器也可用于强制引用完整性,以便在多个表中添加、更新或删除行时,保留在这些表之间所定义的关系。然而,强制引用完整性的最好方法是在相关表中定义主键和外键约束。如果使用数据库关系图,则可以在表之间创建关系以自动创建外键约束。


1.2 工具准备
  • SQL Server

  • Navicat


2. 示例2.1 数据准备

本文代码较多,但多为简单例子,旨在简单说明触发器如何创建及其效果验证。

2.1.1 数据库表判断

首先判断,要使用的数据库中是否存在要使用的表,本触发器以水果销售表与水果库存表为例,SQL 代码如下:

  1. USE test

  2. GO

  3. --本触发器以水果销售表与水果库存表为例

  4. IF EXISTS (SELECT NAME FROM SYSOBJECTS WHERE XTYPE = 'U' AND NAME = 'SGKC')

  5. DROP TABLE SGKC --判断是否存在水果库存表

  6. GO

  7. IF EXISTS (SELECT NAME FROM SYSOBJECTS WHERE XTYPE = 'U' AND NAME = 'SGXS')

  8. DROP TABLE SGXS --判断是否存在水果销售表

  9. GO
复制代码
2.1.2 数据库表创建

上面判断完成后,下面开始建表,SQL 代码如下:

  1. CREATE TABLE SGXS --创建水果销售表

  2. (

  3. PP VARCHAR(40) PRIMARY KEY NOT NULL, --水果品牌

  4. GHS VARCHAR(40) NULL, --供货商

  5. XSSL INT NULL, --销售数量

  6. XSDJ MONEY NULL, --销售单价

  7. XSJE MONEY NULL --销售金额

  8. )

  9. GO

  10. --SELECT * FROM SGXS

  11. CREATE TABLE SGKC --创建水果库存表

  12. (

  13. PP VARCHAR(40) PRIMARY KEY NOT NULL, --水果品牌

  14. KCSL INT NULL, --库存数量

  15. KCDJ MONEY NULL, --库存单价

  16. KCJE MONEY NULL --库存金额

  17. )

  18. GO

  19. --SELECT * FROM SGKC
复制代码
2.2 实例测试

数据库表创建完成后,下面开始效果测试。

2.2.1 测试一

创建触发器[T_INSERT_SGKC]

触发器功能:强制执行业务规则,保证插入的数据中,库存金额 = 库存数量 * 库存单价。

注1:每当 SGKC 表发生 INSERT 动作,则引发该触发器。

注2:[INSERTED]、[DELETED]为系统表,不可创建、修改、删除,但可以调用。

注3:这两个系统表的结构同插入数据的表的结构。

SQL 代码如下:

  1. IF EXISTS (SELECT NAME FROM SYSOBJECTS WHERE XTYPE='TR'AND NAME='T_INSERT_SGKC')

  2. DROP TRIGGER T_INSERT_SGKC --如果存在 T_INSERT_SGKC 触发器则删除

  3. GO

  4. CREATE TRIGGER T_INSERT_SGKC

  5. ON SGKC

  6. FOR INSERT

  7. AS

  8. BEGIN TRANSACTION --提交事务处理

  9. UPDATE SGKC

  10. SET KCJE=KCDJ * KCSL

  11. WHERE PP IN(SELECT PP FROM INSERTED)

  12. COMMIT TRANSACTION

  13. GO
复制代码
2.2.2 验证测试一

针对 SGKC 表,插入测试数据:

第一条数据(火龙果)中的数据符合业务规则。

第二条数据(桂圆)中,[库存金额]空,不符合业务规则。

第三条数据(西瓜)中,[库存金额]不等于[库存数量]乘以[库存单价],不符合业务规则。

第四条数据库存数量为 0。

注:插入数据后,检查 SGKC 表中的数据是否 库存金额 = 库存数量* 库存单价。

SQL 代码如下:

  1. INSERT INTO SGKC(PP,KCSL,KCDJ,KCJE)

  2. SELECT '火龙果',10,12,120 UNION ALL

  3. SELECT '桂圆',20,22,NULL UNION ALL

  4. SELECT '西瓜',12,60,500 UNION ALL

  5. SELECT '橘子',0,30,0 GO

  6. --SELECT * FROM SGKC --检验测试数据可以触发触发器
复制代码

测试效果如下图所示:

2.2.3 测试二

创建触发器[T_INSERT_SGXS]

触发器功能:实现业务规则。 业务规则:如果销售的水果品牌不存在库存或者库存为零,则返回错误, 否则则自动减少[卷烟库存表]中对应品牌水果的库存数量和库存金额。

注:每当 SGKC 表发生 INSERT 动作,则引发该触发器。

创建触发器:

  1. IF EXISTS(SELECT NAME FROM SYSOBJECTS WHERE XTYPE='TR' AND NAME='T_INSERT_SGXS') DROP TRIGGER T_INSERT_SGXS GO

  2. CREATE TRIGGER T_INSERT_SGXS --创建触发器 T_INSERT_SGXS ON SGXS FOR INSERT ASBEGIN TRANSACTION --判断库存是否存在或者是否大于 0

  3. IF NOT EXISTS( SELECT KCSL FROM SGKC WHERE PP IN(SELECT PP FROM INSERTED) )BEGIN RAISERROR('错误!该水果不存在库存,不能销售',16,1)

  4. ROLLBACK RETURN END

  5. IF EXISTS( SELECT KCSL FROM SGKC WHERE PP IN(SELECT PP FROM INSERTED) AND KCSL<=0 )BEGIN RAISERROR('错误!该水果库存小于等于 0,不能销售',16,1) ROLLBACK RETURN END
复制代码

SQL 代码如下:

  1. UPDATE SGXS SET XSJE = XSSL * XSDJ WHERE PP IN(SELECT PP FROM INSERTED)

  2. DECLARE @PP VARCHAR(20) SET @PP = (SELECT PP FROM INSERTED)

  3. DECLARE @XSSL INT SET @XSSL = (SELECT XSSL FROM INSERTED)

  4. UPDATE SGKC SET KCSL = KCSL-@XSSL, KCJE=(KCSL-@XSSL)*KCDJ WHERE PP = @PP COMMIT TRANSACTION

  5. GO
复制代码
2.2.4 验证测试二

针对 SGXS 表,插入第一次测试数据,先插入正确数据。

SQL 代码如下:

  1. INSERT INTO SGXS(PP,GHS,XSSL,XSDJ,XSJE) SELECT '西瓜','某供货商',7,60,420

  2. GO

  3. SELECT * FROM SGXS --验证是否销售表中已经插入该信息

  4. SELECT * FROM SGKC --验证库存表中该水果是否已经扣除数量并修改相应库存金额

  5. GO
复制代码

测试效果如下图所示:

2.2.5 验证测试二

针对 SGXS 表,插入第二次测试数据,插入错误数据,该数据销售金额 不等于销售单价*销售数量。

注:触发器将自动更正数据,使得销售金额不等于销售单价*销售数量。

SQL 代码如下:

  1. INSERT INTO SGXS(PP,GHS,XSSL,XSDJ,XSJE) SELECT '桂圆','某供货商',10,22,2000 GO

  2. SELECT * FROM SGXS --验证是否销售表中已经插入该信息,并且自动修改销售金额

  3. SELECT * FROM SGKC --验证库存表中该水果是否已经扣除数量并修改相应库存金额
复制代码

测试效果如下图所示:

2.2.6 验证测试二

针对 SGXS 表,插入第三次测试数据,该数据中的水果品牌在水果库存中找不到对应,触发器报错。

SQL 代码如下:

  1. INSERT INTO SGXS(PP,GHS,XSSL,XSDJ,XSJE) SELECT '苹果','某供货商',7,20,140

  2. GO
复制代码

测试效果如下图所示:

2.2.7 验证测试二

针对 SGXS 表,插入第四次测试数据,该数据中的水果品牌在水果库存中库存为 0,触发器报错。

SQL 代码如下:

  1. INSERT INTO SGXS(PP,GHS,XSSL,XSDJ,XSJE) SELECT '橘子','某供货商',30,30,900

  2. GO
复制代码

测试效果如下图所示:

3. 示例下载

点击下载上述所有实例: 实例.rar (1.8 KB, 下载次数: 32)




编辑于 2020-9-25 17:09  
分享扩散:

沙发
发表于 2020-9-26 08:05:29
6666666666666666
板凳
发表于 2020-9-27 08:47:37
哈哈哈哈怎么把我的文章搬到论坛了
地板
发表于 2020-9-27 22:05:40
一直有个疑问,,,

frp  的  填报,   为什么 sql  表触发器,不能监督到 insert 行为呢??

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

4回帖数 6关注人数 7046浏览人数
最后回复于:2020-9-27 22:05

返回顶部 返回列表