定义: 何为触发器?在SQL Server里面也就是对某一个表的一定的 *** 作,触发某种条件,从而执行的一段程序。触发器是一个特殊的存储过程。
常见的触发器有三种:分别应用于Insert , Update , Delete 事件。
我为什么要使用触发器?比如,这么两个表:
Create Table Student( --学生表
StudentID int primary key, --学号
....
)
Create Table BorrowRecord( --学生借书记录表
BorrowRecord int identity(1,1), --流水号
StudentID int ,--学号
BorrowDate datetime,--借出时间
ReturnDAte Datetime,--归还时间
...
)
用到的功能有:
1.如果我更改了学生的学号,我希望他的借书记录仍然与这个学生相关(也就是同时更改借书记录表的学号)
2.如果该学生已经毕业,我希望删除他的学号的同时,也删除它的借书记录。
等等。
这时候可以用到触发器。对于1,创建一个Update触发器:
Create Trigger truStudent
On Student --在Student表中创建触发器
for Update --为什么事件触发
As--事件触发后所要做的事情
if Update(StudentID)
begin
Update BorrowRecord
Set StudentID=i.StudentID
From BorrowRecord br , Deleted d ,Inserted i --Deleted和Inserted临时表
Where br.StudentID=d.StudentID
end
理解触发器里面的两个临时的表:Deleted , Inserted 。注意Deleted 与Inserted分别表示触发事件的表“旧的一条记录”和“新的一条记录”。
一个数据库系统中有两个虚拟表用于存储在表中记录改动的信息,分别是:
虚拟表Inserted 虚拟表Deleted
在表记录新增时 存放新增的记录 不存储记录
修改时 存放用来更新的新记录 存放更新前的记录
删除时 不存储记录 存放被删除的记录
一个Update 的过程可以看作为:生成新的记录到Inserted表,复制旧的记录到Deleted表,然后删除Student记录并写入新纪录。
对于2,创建一个Delete触发器
Create trigger trdStudent
On Student
for Delete
As
Delete BorrowRecord
From BorrowRecord br , Delted d
Where br.StudentID=d.StudentID
从这两个例子我们可以看到了触发器的关键:A.2个临时的表;B.触发机制。
CREATE TABLE score (id INT PRIMARY KEY,
val VARCHAR(10)
)
CREATE TRIGGER tr_Update_score
ON score
instead of update
AS
BEGIN
IF USER_NAME() = 'dbo'
UPDATE
score
SET
score.val = inserted.val
FROM
score JOIN inserted
ON (score.id = inserted.id)
ELSE
PRINT '你不是 DBO!'
END
insert into score VALUES(1, 'A')
-- 使用 Demo 作为用户名,登录到数据库。
E:\>sqlcmd -S "localhost\SQLEXPRESS" -U Demo -P demo
1>use testwork
2>go
已将数据库上下文更改为 'TestWork'。
1>UPDATE score SET val='B' WHERE id = 1
2>go
(1 行受影响)
你不是 DBO!
1>select * FROM score
2>go
id val
----------- ----------
1 A
(1 行受影响)
-- 使用 *** 作系统验证,登录到数据库。
E:\>sqlcmd -S "localhost\SQLEXPRESS"
1>use testwork
2>go
已将数据库上下文更改为 'TestWork'。
1>UPDATE score SET val='B' WHERE id = 1
2>go
(1 行受影响)
1> select * FROM score
2>go
id val
----------- ----------
1 B
(1 行受影响)
======================
--货物表
CREATE TABLE stock(
id INT,
stock_amount INT
)
--订单表
CREATE TABLE sell(
ID INT,
GoodsID INT,
sell_amount INT
)
-- 库存测试数据:
INSERT INTO stock VALUES (1, 100)
create trigger trgAfterSell
on sell
after insert
as
begin
declare
@cGoodsID as int,
@sell_amount as int,
@nowCount as INT
select @cGoodsID = GoodsID, @sell_amount = sell_amount
from inserted
SELECT @nowCount = stock_amount
FROM stock
where ID = @cGoodsID
IF @nowCount - @sell_amount <0
BEGIN
PRINT '库存量不足,只有 ' + CAST(@nowCount AS varchar)
ROLLBACK
END
ELSE
BEGIN
update stock
set stock_amount = stock_amount - @sell_amount
where ID = @cGoodsID
PRINT '库存量还剩余' + CAST ((@nowCount - @sell_amount) AS varchar)
END
end
1>INSERT INTO sell VALUES(1, 1, 90)
2>go
(1 行受影响)
库存量还剩余10
1>INSERT INTO sell VALUES(1, 1, 20)
2>go
库存量不足,只有 10
消息 3609,级别 16,状态 1,服务器 HOME-BED592453C\SQLEXPRESS,第 1 行
事务在触发器中结束。批处理已中止。
1>select * from sell
2>select * from stock
3>go
ID GoodsID sell_amount
----------- ----------- -----------
1 1 90
(1 行受影响)
id stock_amount
----------- ------------
1 10
(1 行受影响)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)