SQL中触发器的使用
创建触发器 是特殊的存储过程,自动执行,一般不要有返回值
类型:
1.后触发器 (AFTER,FOR)先执行对应语句,后执行触发器中的语句
2.前触发器 并没有真正的执行触发语句(insert,update,delete),而是执行触发后的语句
3.行级触发器 (FOR EACH ROW) 在SQL server 中不存在
商品号为1的库存量:
1.后触发器(实现不同表之间的约束)
--实现在销售量不大于库存量时,每卖出n件商品,对应商品的库存要减n,若销售量大于库存量,则回滚此次操作
IF EXISTS (SELECT *FROM sysobjects WHERE name='tr_SaleCommodity')
DROP TRIGGER tr_SaleCommodity
GO
CREATE TRIGGER tr_SaleCommodity
ON OrderInfo FOR INSERT --FOR/AFTER为后触发器
AS
BEGIN
IF EXISTS (
SELECT * FROM inserted I INNER JOIN CommodityInfo C ON I.CommodityId=C.CommodityId
WHERE I.Amount>C.Amount
)
BEGIN
ROLLBACK --后触发器
PRINT '商品的销售量大于商品的库存量'
END
ELSE
BEGIN
UPDATE CommodityInfo
SET Amount=Amount-(SELECT Amount FROM inserted)
WHERE CommodityId IN
(
SELECT CommodityId FROM inserted
)
END
END
GO
执行:
INSERT INTO OrderInfo(UserId,CommodityId,Amount,PayMoney,PayWay,OrderTime,Confirm,SendGoods)
VALUES('YOUYOU',,,,'网上银行','2014-11-11 00:00:00.000',,)
结果:
注意:1.上一行为销售记录,下一行为商品1的信息
2.卖出10个,库存量由48变为38
3.可以看出以上的销售记录中的Paymoney是不正确的,它的值应该是Amount*OutPrice=10*300,所以需要前触发器来约束
2.前触发器(可以实现行级触发器功能)
--实现了日期校验和支付金额的计算
IF EXISTS(SELECT* FROM sysobjects WHERE name='tr_DateConfim')
DROP TRIGGER tr_DateConfim
GO
CREATE TRIGGER tr_DateConfim
ON OrderInfo INSTEAD OF INSERT ,UPDATE
AS
BEGIN
DECLARE @date datetime
SELECT @date=OrderTime FROM inserted
IF @date BETWEEN '2012-1-1' AND '2015-1-1'
BEGIN
DECLARE @UserId varchar() ,@CommodityId int,@Amount int,@PayMoney money,@PayWay varchar(),@OrderTime datetime,@Confirm int,@SendGoods int
SELECT @UserId=UserId,@CommodityId=CommodityId,@Amount=Amount,@PayWay=PayWay,@OrderTime=OrderTime,@Confirm=Confirm,@SendGoods=SendGoods FROM inserted
DECLARE @outPrice money
SELECT @outPrice=OutPrice FROM CommodityInfo WHERE CommodityId=@CommodityId
SET @PayMoney=@outPrice*@Amount
PRINT 'inserted 中的数据:'+CONVERT(varchar(),@UserId)+' '+CONVERT(varchar(),@CommodityId)+' '+CONVERT(varchar(),@Amount)+' '+CONVERT(varchar(),@PayMoney)+' '+CONVERT(varchar(),@PayWay)+' '+CONVERT(varchar(),@OrderTime)+' '+CONVERT(varchar(),@Confirm)+' '+CONVERT(varchar(),@SendGoods)+' '+CONVERT(varchar(),@outPrice)
INSERT INTO OrderInfo(UserId,CommodityId,Amount,PayMoney,PayWay,OrderTime,Confirm,SendGoods)
SELECT UserId,CommodityId,Amount,@PayMoney,PayWay,OrderTime,Confirm,SendGoods FROM inserted
END
ELSE
PRINT '你插入的数据中的时间只能在 2012-1-1 到 2015-1-1 中间'
END
GO
执行:
INSERT INTO OrderInfo(UserId,CommodityId,Amount,PayWay,OrderTime,Confirm,SendGoods)
VALUES('YOUYOU',,,'网上银行','2013-1-11',,)
注意:这里插入时我并没有定义PayMoney,PayMoney是通过触发器来自动计算的
结果:
日期不正确:
日期正确:
打印信息对应:@UserId+' '+@CommodityId+' '+@Amount+' '+@PayMoney+' '+@PayWay+' '@OrderTime+' '@Confirm+' '+@SendGoods+' '@outPrice
3.行级触发器(错误)
执行结果:
可以看出在SQL server中并不支持行级触发器
SQL中触发器的使用的更多相关文章
- SQL中约束和触发器的停用与启用
如何对SQL中的约束和触发器进行停用与启用,如果有外键约束则相关联表都要进行相应操作. ALTER TABLE TableName CHECK CONSTRAIT ALL --检查约束 ALTER T ...
- SQL server触发器中 update insert delete 分别给写个例子被。
SQL server触发器中 update insert delete 分别给写个例子以及解释下例子的作用和意思被, 万分感谢!!!! 主要想知道下各个语句的书写规范. INSERT: 表1 (ID, ...
- 在Sql Server触发器中判断操作是Insert还是Update还是Delete
在Sql Server触发器中判断操作是Insert还是Update还是Delete DECLARE @IsInsert bit, @IsUpdate bit, @IsDelete ...
- sql server中触发器
触发器是一种特殊类型的存储过程,它不同于之前的我们介绍的存储过程.触发器主要是通过事件进行触发被自动调用执行的.而存储过程可以通过存储过程的名称被调用. Ø 什么是触发器 触发器对表进行插入.更新.删 ...
- SQL Server 触发器
触发器是一种特殊类型的存储过程,它不同于之前的我们介绍的存储过程.触发器主要是通过事件进行触发被自动调用执行的.而存储过程可以通过存储过程的名称被调用. Ø 什么是触发器 触发器对表进行插入.更新.删 ...
- [SQL] SQL Server 触发器
触发器是一种特殊类型的存储过程,它不同于之前的我们介绍的存储过程.触发器主要是通过事件进行触发被自动调用执行的.而存储过程可以通过存储过程的名称被调用. Ø 什么是触发器 触发器对表进行插入.更新.删 ...
- SQL Server 触发器(转)
触发器是一种特殊类型的存储过程,它不同于之前的我们介绍的存储过程.触发器主要是通过事件进行触发被自动调用执行的.而存储过程可以通过存储过程的名称被调用. Ø 什么是触发器 触发器对表进行插入.更新.删 ...
- SQL Server 触发器【转】
触发器是一种特殊类型的存储过程,它不同于之前的我们介绍的存储过程.触发器主要是通过事件进行触发被自动调用执行的.而存储过程可以通过存储过程的名称被调用. Ø 什么是触发器 触发器对表进行插入.更新.删 ...
- SQL中删除某数据库所有trigger及sp
SQL中删除某数据库所有trigger及sp 编写人:CC阿爸 2014-6-14 在日常SQL数据库的操作中,如何快速的删除所有trigger及sp呢 以下有三种方式可快速处理. --第一种 - ...
随机推荐
- JS中如何理解浮点数?
本文由云+社区发表 相信大家在平常的 JavaScript 开发中,都有遇到过浮点数运算精度误差的问题,比如 console.log(0.1+0.2===0.3)// false.在 JavaScri ...
- MySQL+MGR 单主模式和多主模式的集群环境 - 部署手册 (Centos7.5)
MySQL Group Replication(简称MGR)是MySQL官方于2016年12月推出的一个全新的高可用与高扩展的解决方案.MGR是MySQL官方在5.7.17版本引进的一个数据库高可用与 ...
- Go语言如何判断一个chan被关闭
当一个chanel被关闭后,再取出不会阻塞,而是返回零值 package main import "fmt" func main() { c := make(chan int, 5 ...
- FineUI开源版(ASP.Net)开发实践-目录
点我订阅 目前所有博客的截图,方便离线观看,点图片 FineUI初学手册 下载,实例项目搭建 FineUI初学手册-部分JS整理 部分JS整理 ASP.NET-FineUI开发实践-1 实际开发环境是 ...
- Ansible常用模块介绍及使用(week5_day1_part2)--技术流ken
Ansible模块 在上一篇博客<Ansible基础认识及安装使用详解(一)--技术流ken>中以及简单的介绍了一下ansible的模块.ansible是基于模块工作的,所以我们必须掌握几 ...
- Raft 基础
目录 三个状态 什么是任期 节点之间的通信 1. 三个状态 Raft 设计了 3 个状态,用于表示节点的状态,分别是跟随者,候选者,领导者. 领导者:通常只有一个领导人,并且其他节点都是跟随者. 跟随 ...
- [转]BTC RPC API GetTransaction
本文转自: GetTransaction GetTransaction gettransaction调用获取指定钱包内交易的详细信息.该调用需要节点 启用钱包功能. 参数 TXID:要查看详情的交易I ...
- C#面向对象之多态。
1.定义:指不同的对象收到相同的消息时,会产生不同的行为,同一个类在不同的场合下表现出不同的行为特征. 比如. class Program { //下面三各类都继承object,但不同类的tostri ...
- ASP.NET MVC3 在_ViewStart设置Layout使用RenderAction的注意事項
来源:https://dotblogs.com.tw/lastsecret/archive/2012/03/26/71052.aspx ASP.NET MVC3 在_ViewStart設定Layout ...
- 在Java中进行序列化和反序列化
对象序列化的目标是将对象保存在磁盘中,或者允许在网络中直接传输对象. 对象序列化允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久保存在磁盘上或者通过网络将这种二进制流传输 ...