--下面是例子(需要在查询分析器中进行)--创建测试表
create table tb(id int)
go
--创建触发器
create trigger t_insert on tb
for insert
as
print '插入处理触发器'
go--事务处理
begin tran
insert into tb values(1)
print '插入处理'
commit trango
--删除测试表
drop table tb/*--测试结果插入处理触发器(所影响的行数为 1 行)插入处理--*/
create table tb(id int)
go
--创建触发器
create trigger t_insert on tb
for insert
as
print '插入处理触发器'
go--事务处理
begin tran
insert into tb values(1)
print '插入处理'
commit trango
--删除测试表
drop table tb/*--测试结果插入处理触发器(所影响的行数为 1 行)插入处理--*/
預存程序與觸發程序中的復原
如果 @@TRANCOUNT 在預存程序 (Stored Procedure) 完成時的值與預存程序執行時的值不同,便產生資訊式的錯誤 266。這個錯誤在相同條件下的觸發程序 (Trigger) 中不會產生。266 錯誤是在 @@TRANCOUNT 大於或等於 1,且預存程序在執行 ROLLBACK TRANSACTION 或 ROLLBACK WORK 陳述式而被呼叫時產生。這是因為 ROLLBACK 將所有尚未處理完畢的交易復原,並將 @@TRANCOUNT 降為 0,而此值低於呼叫程序時的值所致。如果 ROLLBACK TRANSACTION 是在觸發程序中發出: 在目前交易中進行至該點的所有資料修改都會復原,包括觸發程序所做的修改。
觸發程序繼續執行 ROLLBACK 陳述式之後的其餘陳述式。這其中若有任何修改資料的陳述式,修改動作並不會復原。這些剩餘陳述式的執行並不會引發巢狀觸發程序。
引發觸發程序的陳述式之後的批次中的任何陳述式都不會執行。
觸發程序中的 ROLLBACK 關閉,並把包含引發觸發程序之陳述式的批次中宣告及開啟的資料指標 (Cursor) 全部取消配置。其中包括宣告及開啟於由引發觸發程序之批次所呼叫的預存程序中的資料指標。在引發觸發程序的批次之前的批次中宣告的資料指標只會關閉,但若有下列情況則 STATIC 或 INSENSITIVE 資料指標會保持開啟:
CURSOR_CLOSE_ON_COMMIT 設定為 OFF。
靜態資料指標為同步,或為完整填入的非同步 (Asynchronous) 資料指標。
觸發程序的運作一直像是在執行觸發程序時,會受到尚未處理完畢的交易影響一樣。引發觸發程序的陳述式如果是在隱含交易 (Implicit Transaction) 或外顯交易 (Explicit Transaction) 中,則這種情形永遠為真。自動認可模式亦同。當陳述式開始執行於自動認可模式時,隱含的 BEGIN TRANSACTION 便允許陳述式在遇到錯誤時,將自己產生的一切修改復原。這個隱含的交易不會影響到批次中的其他陳述式,因為它會在陳述式完成時被認可或復原。但是,當呼叫某個觸發程序時,此隱含的交易仍然有影響。這表示一旦在觸發程序中提交 BEGIN TRANSACTION 陳述式則實際上便開始巢狀交易。由於在復原巢狀交易時,會忽略巢狀的 BEGIN TRANSACTION 陳述式,因此在觸發程序中提交的 ROLLBACK TRANSACTION,會略過觸發程序本身所提交的 BEGIN TRANSACTION 陳述式而永遠復原。ROLLBACK 復原至最外側的 BEGIN TRANSACTION。您必須在觸發程序中使用 SAVE TRANSACTION 陳述式來進行部分復原,即使這個陳述式總是在自動認可模式下被呼叫。下列觸發程序說明了這一點:CREATE TRIGGER TestTrig ON TestTab FOR UPDATE AS
SAVE TRANSACTION MyName
INSERT INTO TestAudit
SELECT * FROM inserted
IF (@@error <> 0)
BEGIN
ROLLBACK TRANSACTION MyName
END這同時也會影響到觸發程序中,接續 BEGIN TRANSACTION 陳述式的 COMMIT TRANSACTION 陳述式。由於 BEGIN TRANSACTION 啟動巢狀交易,後續的 COMMIT 陳述式便僅套用於巢狀交易。如果 ROLLBACK TRANSACTION 陳述式是在 COMMIT 之後執行,ROLLBACK 則將一切都復原到最外側的 BEGIN TRANSACTION。下列觸發程序說明了這一點:CREATE TRIGGER TestTrig ON TestTab FOR UPDATE AS
BEGIN TRANSACTION
INSERT INTO TrigTarget
SELECT * FROM inserted
COMMIT TRANSACTION
ROLLBACK TRANSACTION上述觸發程序永遠不會插入到 TrigTarget 資料表。BEGIN TRANSACTION 啟動的會是巢狀交易。COMMIT TRANSACTION 僅認可巢狀交易,而接續的 ROLLBACK TRANSACTION 則將一切都復原到最外層的 BEGIN TRANSACTION。