我們這里介紹兩個特殊的表,Inserted表和Deleted表。此二表僅僅在觸發器運行時存在。你可以使用該兩個表來精確地確定觸發觸發器的動作對數據表所做的修改。比如,通過檢查Deleted表,你可以確定那些記錄由某一動作刪除。考慮下面的例子:
CREATE TRIGGER tr_webusers_delete ON webusers
FOR DELETE
AS
INSERT weblog (activity) SELECT user_name FROM Deleted
該觸發器自動地創建一個webusers表的記錄。當在webusers表內刪除一個用戶的姓名時,觸發器會自動地把該姓名插入到weblog表中。假設你一不小心執行了下面的語句:
DELETE webusers
該語句會刪除在webusers表內的所有記錄。一般地,這些記錄會永久地丟失,然而上面的觸發器會在有記錄從webusers表中刪除時自動的觸發。該觸發器會檢查表Deleted來確定有那些在webusers表內的記錄被刪除,並且把所有刪除了的記錄拷貝到weblog表中。
為了恢復那些意外被刪除的記錄,你可以使用INSERT和SELECT語句再一次把它們從weblog表中拷貝到webusers表中。如果你不能允許意外地丟失一條記錄時,你可以使用上面的方法來創建一個表內數據的備份。
Deleted表和有記錄被刪除的表的列結構一模一樣。在前面的例子內,Deleted表具有和webusers表相同的結構。
現在假定你想跟蹤所有插入某一表格的記錄。比如,你想把每一條插入webusers表內的記錄都在weblog表內做備份,你可以使用下面的觸發器來完成該任務:
CREATE TRIGGER tr_webusers_insert ON webusers
FOR INSERT
AS
INSERT weblog(activty) SELECT user_name FROM INSERTED
該觸發器和前面的觸發器非常相似,除了以下兩點以外:
該觸發器在有記錄插入表格webusers時觸發;該觸發器是FOR INSERT。
該觸發器把記錄從Inserted表拷貝到weblog表內。
Inserted表內包含了所有已經插入到表內的新記錄。假如一個新用戶的姓名插入到webusers表內時,觸發器會自動地把新的用戶姓名從webusers表拷貝到weblog表內。
當你想使用一個簡單的表來記錄所有發生在你數據庫中一個非常重要的表的動作時,這種復制數據的方法非常有用。你可以使用該表來獲得對你的數據庫的活動的記錄,並且可以用於記錄和診斷一些可能發生的問題。
你同樣可以使用Inserted表和Deleted表來記錄UPDATE對觸發器所在的表所做的改動。當一個和觸發器相關的表內的數據被修改時,Deleted表包含了所有列在修改之前的值,而Inserted表包含了所有列在修改之后的值。參看下面的表12.2,以明確每一個動作是如何影響Deleted和Inserted表的。
表12.2.Inserted和Deleted表的內容
表 |
INSERT |
DELETE |
UPDATE |
Inserted |
插入列 |
空 |
修改前的列 |
Deleted |
空 |
刪除列 |
修改后的列 |
使用 inserted 和 deleted 表
(2009-03-12 12:44:13)
轉載
標簽: 雜談 |
分類: 工作所用 |
使用 inserted 和 deleted 表 updated
觸發器語句中使用了兩種特殊的表:deleted 表和 inserted 表。Microsoft® SQL Server™ 2000 自動創建和管理這些表。可以使用這兩個臨時的駐留內存的表測試某些數據修改的效果及設置觸發器操作的條件;然而,不能直接對表中的數據進行更改。
inserted 和 deleted 表主要用於觸發器中:
擴展表間引用完整性。
在以視圖為基礎的基表中插入或更新數據。
檢查錯誤並基於錯誤采取行動。
找到數據修改前后表狀態的差異,並基於此差異采取行動。
Deleted 表用於存儲 DELETE 和 UPDATE 語句所影響的行的復本。在執行 DELETE 或 UPDATE 語句時,行從觸發器表中刪除,並傳輸到 deleted 表中。Deleted 表和觸發器表通常沒有相同的行。
Inserted 表用於存儲 INSERT 和 UPDATE 語句所影響的行的副本。在一個插入或更新事務處理中,新建行被同時添加到 inserted 表和觸發器表中。Inserted 表中的行是觸發器表中新行的副本。
更新事務類似於在刪除之后執行插入;首先舊行被復制到 deleted 表中,然后新行被復制到觸發器表和 inserted 表中。
在設置觸發器條件時,應當為引發觸發器的操作恰當使用 inserted 和 deleted 表。雖然在測試 INSERT 時引用 deleted 表或在測試 DELETE 時引用 inserted 表不會引起任何錯誤,但是在這種情形下這些觸發器測試表中不會包含任何行。
說明 如果觸發器操作取決於一個數據修改所影響的行數,應該為多行數據修改(基於 SELECT 語句的 INSERT、DELETE 或 UPDATE)使用測試(如檢查 @@ROWCOUNT),然后采取相應的對策。
1.插入操作(Insert)
Inserted表有數據,Deleted表無數據
2.刪除操作(Delete)
Inserted表無數據,Deleted表有數據
3.更新操作(Update)
Inserted表有數據(新數據),Deleted表有數據(舊數據)
SQL Server™ 2000 不允許 AFTER 觸發器引用 inserted 和 deleted 表中的 text、ntext 或 image 列;然而,允許 INSTEAD OF 觸發器引用這些列。有關更多信息,請參見 CREATE TRIGGER。
Inserted為空,Deleted不為空 --Delete
Inserted不為空,Deleted為空 --Insert
Inserted不為空,Deleted不為空 --Update
alter TRIGGER update_oatable_state
ON oatable
FOR update
AS
declare @zid nvarchar(100)
declare @sub2 nvarchar(100)
select @zid=zid, @sub2=sub2 from updated
update T_P_OA_ZZWJGL set v5=@sub2 where zid = @zid
GO
如果你保證每次只更新一條記錄:
CREATE TRIGGER UpdateUser ON dbo.[user]
after update
AS
update users set userid=new.UserName,[password]=new.UserPassword from inserted new where users.userid=(select username from deleted)
go