本文摘自《鋒利的SQL》:http://item.jd.com/10380652.html
在前面討論的一直都是AFTER觸發器。INSTEAD OF在處理約束前激發,可以在INSTEAD OF中使用其他語句來替代激發觸發器的INSERT、UPDATE等語句。
可以爲表或視圖定義INSTEADOF觸發器,但是,INSTEADOF觸發器的主要優點是可以使不能更新的視圖支持更新。基於多個基表的視圖必須使用INSTEAD OF觸發器來對多個表中的數據進行插入、更新和刪除操作。INSTEAD OF觸發器的另一個優點是允許在批處理中某些部分成功的同時,能夠拒絕批處理中的其他部分。
1.爲表創建INSTEAD OF觸發器
與AFTER觸發器相同,INSTEAD OF觸發器也需要指定其適用的操作類型,包括INSERT、UPDATE和DELETE操作。要創建一個INSTEAD OF觸發器,必須在CREATE TRIGGER語句中使用INSTEAD OF關鍵字,而不是AFTER或FOR關鍵字。
例如,下面的示例創建了一個Employee表,該表的EmployeeName列具有主鍵約束。創建的EmpInsteadInsert觸發器用於INSERT操作,只有在僱員姓名在表中不存在時,才插入新行。如果發現要插入的僱員姓名在表中已經存在,僅更新該僱員的地址信息。因此,該表永遠也不會違反主鍵約束。
USE AdventureWorks;
GO
-- 創建表
CREATE TABLE Employee (
EmployeeName char(30) PRIMARY KEY,
Addresschar(30)
);
GO
-- 創建觸發器,當有重複僱員名稱時,更新該僱員的地址信息
CREATE TRIGGER EmpInsteadInsert
ON Employee
INSTEAD OF INSERT
AS
IFEXISTS(
SELECT *
FROMEmployee E, Inserted I
WHEREE.EmployeeName = I.EmployeeName)
BEGIN
UPDATE Employee
SETAddress = Inserted.Address
FROMInserted
WHEREEmployee.EmployeeName = Inserted.EmployeeName;
END
ELSE
BEGIN
INSERT INTO Employee
SELECT * FROM Inserted;
END
執行下面的測試語句,得到的結果集如圖14-5所示。
-- 下面這兩個僱員的姓名在表中不存在,可以正常插入
INSERT INTO Employee VALUES('Harry','Chicago');
INSERT INTO Employee VALUES('Alice','Washington');
SELECT * FROM Employee; -- 查看結果集
-- 由於Harry在表中已經存在了,則僅修改Harry的地址信息
INSERT INTO Employee VALUES('Harry','Washington');
SELECT * FROM Employee;