您的位置:首页 > 数据库

SQL Server 触发器的学习

2012-02-10 01:32 323 查看
这两天VMI的项目出了很多小问题,主要是sourcing部门对已经注册VMI的料进行大批量的删除和价格更新,这让原本存在的VMI订单来不及取消,或者VMI发票上的单价与实际系统中的单价产生了一定的差异。于是先通过trigger来控制,开始用c#以来很久没碰trigger了,创建之前先学习一下;

基于需求,这里测试主要是基于DML操作,另外要求在游标中使用cursor来达到批量操作的目的,另外需要对insert/delete/update分别测试,以适应需求;

<从codeproject找了一个简单的例子>

CREATE TABLE Employee_Test
(
Emp_ID INT Identity,
Emp_name Varchar(100),
Emp_Sal Decimal (10,2)
)

INSERT INTO Employee_Test VALUES ('Anees',1000);
INSERT INTO Employee_Test VALUES ('Rick',1200);
INSERT INTO Employee_Test VALUES ('John',1100);
INSERT INTO Employee_Test VALUES ('Stephen',1300);
INSERT INTO Employee_Test VALUES ('Maria',1400);

CREATE TABLE Employee_Test_Audit
(
Emp_ID int,
Emp_name varchar(100),
Emp_Sal decimal (10,2),
Audit_Action varchar(100),
Audit_Timestamp datetime
)

1). Insert , 支持批量,

ALTER TRIGGER tradertest ON Employee_Test
FOR INSERT
as
DECLARE @empsal INT,@empname VARCHAR(100)
DECLARE @cur_1 CURSOR
SET @cur_1 = CURSOR FOR
SELECT Emp_Sal,Emp_name FROM inserted
OPEN @cur_1
FETCH NEXT FROM @cur_1 INTO @empsal,@empname
WHILE @@FETCH_STATUS=0
BEGIN
INSERT INTO Employee_Test_Audit (Emp_Sal,Emp_name) VALUES (@empsal,@empname)
FETCH NEXT FROM @cur_1 INTO @empsal,@empname
END
CLOSE @cur_1
DEALLOCATE @cur_1
GO
INSERT INTO Employee_Test (Emp_name,Emp_Sal)
SELECT TOP 10 Emp_name,Emp_Sal FROM Employee_Test
GO
SELECT * FROM  Employee_Test_Audit

2) Delete 操作,在里面进行判断,如果是删除John的薪水,需要保留到audit表中:

alter TRIGGER traderDel ON Employee_Test
FOR DELETE
as
DECLARE @empsal FLOAT,@empname VARCHAR(100)
DECLARE @cur_1 CURSOR
SET @cur_1 = CURSOR FOR
SELECT Emp_Sal,Emp_name FROM DELETED
OPEN @cur_1
FETCH NEXT FROM @cur_1 INTO @empsal,@empname
WHILE @@FETCH_STATUS=0
BEGIN
--- 循环里面加以判断,如果是John则禁止删除
IF @empname='John'
INSERT INTO Employee_Test_Audit (Emp_Sal,Emp_name,Audit_Action) VALUES
(@empsal,@empname,'Delete John Sal')
FETCH NEXT FROM @cur_1 INTO @empsal,@empname
END
CLOSE @cur_1
DEALLOCATE @cur_1
GO
DELETE Employee_Test WHERE Emp_Sal=1100
GO
SELECT * FROM Employee_Test_Audit WHERE Audit_Action LIKE 'Delet%'


3) Update, 要求把对修改薪水的操作记录下来:

ALTER TRIGGER traderUpd ON Employee_Test
FOR UPDATE
as
DECLARE @empsal FLOAT,@empname VARCHAR(100),@i int
DECLARE @cur_1 CURSOR
SET @i=1
SET @cur_1 = CURSOR FOR
SELECT Emp_Sal,Emp_name FROM DELETED
OPEN @cur_1
FETCH NEXT FROM @cur_1 INTO @empsal,@empname
WHILE @@FETCH_STATUS=0
BEGIN
---此处用Emp_Sal来进行对比,如果相等不操作,否则记录并报错;
IF @empsal<>(SELECT MAX(Emp_Sal) FROM INSERTED WHERE Emp_name=@empname)
BEGIN
INSERT Employee_Test_Audit (Emp_Sal,Emp_name,Audit_Timestamp)
VALUES (@empsal,@empname,GETDATE())
RAISERROR(N'Cant udpate his salary!',1,50);
END
FETCH NEXT FROM @cur_1 INTO @empsal,@empname
END
CLOSE @cur_1
DEALLOCATE @cur_1

UPDATE Employee_Test SET Emp_sal=1000 WHERE Emp_name='Rick'
SELECT * FROM Employee_Test_Audit
SELECT * FROM Employee_Test

总结,Trigger的内容还有很多,以上只是针对DML的简单操作,另外加入了批量功能,帮助自己温习一下trigger.仅供参考。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: