这两天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.仅供参考。