DML AFTER UPDATE觸發器創建原理
觸發器觸發時,系統自動在內存中創建deleted表或inserted表,inserted表臨時保存了插入或更新后的記錄行,deleted表臨時保存了刪除或更新前的記錄行,內存中創建的表只讀,不允許修改,觸發器執行完成后,自動刪除。
update觸發器工作原理:第一步執行update更新語句,第二步觸發update觸發器刪除原有的數據,將刪除的數據備份到deleted表中,第三步再插入新行數據,將新插入的數據備份到inserted表中。
不能使用SSMS數據庫管理工具直接創建DML添加觸發器,可以使用T-SQL腳本創建DML添加觸發器。
DML AFTER UPDATE觸發器創建
語法:
--聲明數據庫引用
use 數據庫名;
go
--判斷觸發器是否存在
if exists(select * from sysobjects where name=觸發器名)
drop trigger 觸發器名;
go
--創建新的修改觸發器
create
--觸發器標識符
trigger
--DML 觸發器所屬架構的名稱。 DML 觸發器的作用域是為其創建該觸發器的表或視圖的架構。 不能為 DDL 或登錄觸發器指定
--[dbo.]
--觸發器名稱
觸發器名稱
on
--對其執行 DML 觸發器的表或視圖,有時稱為觸發器表或觸發器視圖。 可以根據需要指定表或視圖的完全限定名稱。 視圖只能被 INSTEAD OF 觸發器引用。 不能對局部或全局臨時表定義 DML 觸發器。
[架構名稱.] { 表名 | 視圖名 }
--with
--對CREATE TRIGGER 語句的文本進行模糊處理。使用WITH ENCRYPTION可以防止將觸發器作為SQL Server復制的一部分進行發布。不能為 CLR 觸發器指定 WITH ENCRYPTION。(指定此選項將為觸發器加密)
--encryption,
--指示觸發器已本機編譯。 (只能應用於table)
--內存優化表上的觸發器需要使用此選項。
--native_compilation
--確保不能刪除或更改觸發器引用的表。(只能應用於table)
--內存優化表上的觸發器需要使用此選項,但此選項不支持傳統表上的觸發器。
--schemabinding
--EXECUTE AS (后面可以跟函數,存儲過程等)
--指定用於執行該觸發器的安全上下文。 允許您控制 SQL Server 實例用於驗證被觸發器引用的任意數據庫對象的權限的用戶帳戶。
--內存優化表上的觸發器需要使用此選項。
--execute as clause
--FOR | AFTER
--AFTER 指定 DML 觸發器僅在觸發 SQL 語句中指定的所有操作都已成功執行時才被觸發。 所有的引用級聯操作和約束檢查也必須在激發此觸發器之前成功完成。
--如果僅指定 FOR 關鍵字,則 AFTER 為默認值。
--不能對視圖定義 AFTER 觸發器。
{ for | after }
--{ [DELETE] [,] [INSERT] [,] [UPDATE] }
--指定數據修改語句,這些語句可在 DML 觸發器對此表或視圖進行嘗試時激活該觸發器。 必須至少指定一個選項。 在觸發器定義中允許使用上述選項的任意順序組合。
--對於 INSTEAD OF 觸發器,不允許對具有指定級聯操作 ON DELETE 的引用關系的表使用 DELETE 選項。 同樣,也不允許對具有指定級聯操作 ON UPDATE 的引用關系的表使用 UPDATE 選項。
{ [insert] [,] [update] [,] [delete] }
--指定應該再添加一個現有類型的觸發器。 WITH APPEND 不能與 INSTEAD OF 觸發器一起使用。如果顯式聲明了 AFTER 觸發器,則也不能使用該子句。
--僅當為了向后兼容而指定了 FOR 時(但沒有 INSTEAD OF 或 AFTER)時,才能使用 WITH APPEND。 如果指定了 EXTERNAL NAME(即觸發器為 CLR 觸發器),則不能指定 WITH APPEND。
--with append
--指示當復制代理修改涉及到觸發器的表時,不應執行觸發器。
--not for replication
as
begin
sql_statement
end
go
示例:
--聲明數據庫引用
use testss;
go
--判斷觸發器是否存在
if exists(select * from sysobjects where name='updatetri')
drop trigger updatetri;
go
--創建新的修改觸發器
create
--觸發器標識符
trigger
--DML 觸發器所屬架構的名稱。 DML 觸發器的作用域是為其創建該觸發器的表或視圖的架構。 不能為 DDL 或登錄觸發器指定
--[dbo.]
--觸發器名稱
updatetri
on
--對其執行 DML 觸發器的表或視圖,有時稱為觸發器表或觸發器視圖。 可以根據需要指定表或視圖的完全限定名稱。 視圖只能被 INSTEAD OF 觸發器引用。 不能對局部或全局臨時表定義 DML 觸發器。
dbo.test1
--with
--對CREATE TRIGGER 語句的文本進行模糊處理。使用WITH ENCRYPTION可以防止將觸發器作為SQL Server復制的一部分進行發布。不能為 CLR 觸發器指定 WITH ENCRYPTION。(指定此選項將為觸發器加密)
--encryption,
--指示觸發器已本機編譯。 (只能應用於table)
--內存優化表上的觸發器需要使用此選項。
--native_compilation
--確保不能刪除或更改觸發器引用的表。(只能應用於table)
--內存優化表上的觸發器需要使用此選項,但此選項不支持傳統表上的觸發器。
--schemabinding
--EXECUTE AS (后面可以跟函數,存儲過程等)
--指定用於執行該觸發器的安全上下文。 允許您控制 SQL Server 實例用於驗證被觸發器引用的任意數據庫對象的權限的用戶帳戶。
--內存優化表上的觸發器需要使用此選項。
--execute as clause
--FOR | AFTER
--AFTER 指定 DML 觸發器僅在觸發 SQL 語句中指定的所有操作都已成功執行時才被觸發。 所有的引用級聯操作和約束檢查也必須在激發此觸發器之前成功完成。
--如果僅指定 FOR 關鍵字,則 AFTER 為默認值。
--不能對視圖定義 AFTER 觸發器。
for
--{ [DELETE] [,] [INSERT] [,] [UPDATE] }
--指定數據修改語句,這些語句可在 DML 觸發器對此表或視圖進行嘗試時激活該觸發器。 必須至少指定一個選項。 在觸發器定義中允許使用上述選項的任意順序組合。
--對於 INSTEAD OF 觸發器,不允許對具有指定級聯操作 ON DELETE 的引用關系的表使用 DELETE 選項。 同樣,也不允許對具有指定級聯操作 ON UPDATE 的引用關系的表使用 UPDATE 選項。
update
--指定應該再添加一個現有類型的觸發器。 WITH APPEND 不能與 INSTEAD OF 觸發器一起使用。如果顯式聲明了 AFTER 觸發器,則也不能使用該子句。
--僅當為了向后兼容而指定了 FOR 時(但沒有 INSTEAD OF 或 AFTER)時,才能使用 WITH APPEND。 如果指定了 EXTERNAL NAME(即觸發器為 CLR 觸發器),則不能指定 WITH APPEND。
--with append
--指示當復制代理修改涉及到觸發器的表時,不應執行觸發器。
not for replication
as
begin
declare @oldname nvarchar(100)=null,@newname nvarchar(100)=null;
set @oldname=(select top(1) deleted.name from deleted order by id desc);
set @newname=(select top(1) inserted.name from inserted order by id desc);
if @oldname is not null
begin
update dbo.test2 set name=@newname where id=(select id from dbo.test2 where name=@oldname)
end
end
go
示例結果:
DML AFTER UPDATE觸發器優缺點
優點:
1、觸發器可以更快更高效的維護數據,節省人力。
2、觸發器可以用於加強數據的完整性約束和業務規則。
缺點:
1、可移植性差。
2、占用服務器資源,給服務器造成壓力。
3、執行速度主要取決於數據庫服務器的性能與觸發器代碼的復雜程度。
4、觸發器會使編程時源碼的結構被迫打亂,為將程序修改、源碼閱讀帶來困難。