SQLServer之修改觸發器

修改觸發器規則

修改CREATE TRIGGER語句之前建立的 DML、DDL 或登陸觸發器的定義。觸發器是經過使用CREATE TRIGGER建立的。這些觸發器能夠由Transact-SQL語句直接建立,也能夠由程序集方法建立,這些方法在Microsoft .NET Framework公共語言運行時 (CLR)中建立並上傳到SQL Server的實例。sql

DML 觸發器

經過表和視圖上的INSTEAD OF觸發器,ALTER TRIGGER支持可手動更新的視圖。SQL Server以相同的方式對全部類型的觸發器(AFTER、INSTEAD-OF)應用ALTER TRIGGER。數據庫

可使用sp_settriggerorder來指定要對錶執行的第一個和最後一個AFTER觸發器。 對一個表只能指定第一個和最後一個AFTER觸發器。 若是在同一個表上還有其餘AFTER觸發器,這些觸發器將隨機執行。服務器

若是ALTER TRIGGER語句更改了第一個或最後一個觸發器,將刪除所修改觸發器上設置的第一個或最後一個屬性,而且必須使用sp_settriggerorder重置順序值。架構

只有在成功執行觸發SQL語句以後,纔會執行AFTER觸發器。 判斷執行成功的標準是:執行了全部與已更新對象或已刪除對象相關聯的引用級聯操做和約束檢查。 AFTER 觸發器操做要檢查觸發語句的效果,也包括全部由觸發語句引發的 UPDATE 和 DELETE 引用級聯操做。優化

若是一個子表或引用表上的 DELETE 操做是因爲父表的 CASCADE DELETE 操做所引發的,而且子表上定義了 DELETE 的 INSTEAD OF 觸發器,那麼將忽略該觸發器並執行 DELETE 操做。加密

DDL 觸發器

與DML觸發器不一樣,DDL觸發器的做用域不是架構。 所以,在查詢有關DDL觸發器的元數據時,不能使用OBJECT_ID、OBJECT_NAME、OBJECTPROPERTY 和 OBJECTPROPERTY(EX)。 請改用目錄視圖。 有關詳細信息,請參閱獲取有關 DDL 觸發器的信息。spa

登陸觸發器

Azure SQL Database 不支持針對登陸事件的觸發器。代理

Permissions

若要更改DML觸發器,須要對於定義該觸發器所在的表或視圖擁有 ALTER 權限。server

若要更改定義了服務器範圍 (ON ALL SERVER) 的DDL觸發器或者更改登陸觸發器,須要對該服務器擁有CONTROL SERVER權限。 若要更改定義了數據庫範圍 (ON DATABASE) 的DDL觸發器,須要對當前數據庫擁有ALTER ANY DATABASE DDL TRIGGER權限。xml

觸發器修改

語法:

--聲明數據庫引用
use 數據庫;
go

--修改觸發器
alter

--觸發器標識符
trigger

--DML觸發器所屬架構的名稱。 DML觸發器的做用域是爲其建立該觸發器的表或視圖的架構。不能爲DDL或登陸觸發器指定
--dbo觸發器名稱
[架構名稱].[觸發器名]

on

--對其執行DML觸發器的表或視圖,有時稱爲觸發器表或觸發器視圖。能夠根據須要指定表或視圖的徹底限定名稱。視圖只能被INSTEAD OF觸發器引用。不能對局部或全局臨時表定義DML觸發器。

--DATABASE

--將 DDL 觸發器的做用域應用於當前數據庫。 若是指定了此參數,則只要當前數據庫中出現 event_type 或 event_group,就會激發該觸發器。

--ALL SERVER
--適用範圍: SQL Server 2008 到 SQL Server 2017。

--將 DDL 或登陸觸發器的做用域應用於當前服務器。 若是指定了此參數,則只要當前服務器中的任何位置出現 event_type 或 event_group,就會激發該觸發器。

{ [架構名].表名| [架構名].視圖 } { database| all server } { all server }

--with
--此屬性適用於全部觸發器類型
--加密包含ALTER TRIGGER語句文本的sys.syscomments和sys.sql_modules項。使用WITH ENCRYPTION能夠防止將觸發器做爲SQL Server複製的一部分進行發佈。不能爲CLR觸發器指定WITH ENCRYPTION。
--encryption,

--指示觸發器已本機編譯。(只能應用於DML觸發器的table)
--內存優化表上的觸發器須要使用此選項。
--native_compilation,

--確保不能刪除或更改觸發器引用的表。(只能應用於DML觸發器的table)
--內存優化表上的觸發器須要使用此選項,但此選項不支持傳統表上的觸發器。
--schemabinding

--此屬性適用於全部觸發器類型
--{ EXEC | EXECUTE } AS { SELF | OWNER | 'user_name' }
--CALLER
--指定模塊內的語句在模塊調用方的上下文中執行。 執行模塊的用戶不只必須對模塊自己擁有適當的權限,還要對模塊引用的任何數據庫對象擁有適當權限。
--CALLER 是除隊列外的全部模塊的默認值,與 SQL Server 2005 行爲相同。
--CALLER 不能在 CREATE QUEUE 或 ALTER QUEUE 語句中指定。
--SELF
--EXECUTE AS SELF 與 EXECUTE AS user_name 等價,其中指定用戶是建立或更改模塊的用戶。 建立或更改模塊的用戶的實際用戶 ID 存儲在 sys.sql_modules 或 sys.service_queues 目錄視圖的 execute_as_principal_id 列中。
--SELF 是隊列的默認值。
--OWNER
--指定模塊內的語句在模塊的當前全部者上下文中執行。 若是模塊沒有指定的全部者,則使用模塊架構的全部者。 不能爲 DDL 或登陸觸發器指定 OWNER。
--' user_name '
--指定模塊內的語句在 user_name 指定的用戶的上下文中執行。 將根據 user_name 來驗證對模塊內任意對象的權限。 不能爲具備服務器做用域的 DDL 觸發器或登陸觸發器指定 user_name。 請改用 login_name。
--user_name 必須存在於當前數據庫中,而且必須是單一實例賬戶。 user_name 不能爲組、角色、證書、密鑰或內置賬戶,如 NT AUTHORITYLocalService、NT AUTHORITYNetworkService 或 NT AUTHORITYLocalSystem。
--執行上下文的用戶 ID 存儲在元數據中,能夠在 sys.sql_modules 或 sys.assembly_modules 目錄視圖的 execute_as_principal_id 列查看。
--內存優化表上的觸發器須要使用此選項。
--execute as { caller | self | owner | 'username'}

--FOR | AFTER
--AFTER 指定 DML 觸發器僅在觸發 SQL 語句中指定的全部操做都已成功執行時才被觸發。 全部的引用級聯操做和約束檢查也必須在激發此觸發器以前成功完成。
--若是僅指定 FOR 關鍵字,則 AFTER 爲默認值。
--不能對視圖定義 AFTER 觸發器。

--INSTEAD OF

--指定執行 DML 觸發器而不是觸發 SQL 語句,所以,其優先級高於觸發語句的操做。 不能爲 DDL 或登陸觸發器指定 INSTEAD OF。

--對於表或視圖,每一個 INSERT、UPDATE 或 DELETE 語句最多可定義一個 INSTEAD OF 觸發器。 可是,能夠爲具備本身的 INSTEAD OF 觸發器的多個視圖定義視圖。

--不容許在使用 WITH CHECK OPTION 建立的視圖上定義 INSTEAD OF 觸發器。 將 INSTEAD OF 觸發器添加到爲其指定了 WITH CHECK OPTION 的視圖時, SQL Server 將引起錯誤。 用戶必須用 ALTER VIEW 刪除該選項後才能定義 INSTEAD OF 觸發器。

{ for | after | instead of }

--{ [DELETE] [,] [INSERT] [,] [UPDATE] }
--指定數據修改語句,這些語句可在 DML 觸發器對此表或視圖進行嘗試時激活該觸發器。 必須至少指定一個選項。 在觸發器定義中容許使用上述選項的任意順序組合。
--對於 INSTEAD OF 觸發器,不容許對具備指定級聯操做 ON DELETE 的引用關係的表使用 DELETE 選項。 一樣,也不容許對具備指定級聯操做 ON UPDATE 的引用關係的表使用 UPDATE 選項。

--event_type

--執行以後將致使激發 DDL 觸發器的 Transact-SQL 語言事件的名稱。 DDL 事件中列出了 DDL 觸發器的有效事件。

--event_group
--預約義的 Transact-SQL 語言事件分組的名稱。 執行任何屬於 event_group 的 Transact-SQL 語言事件以後,都將激發 DDL 觸發器。 DDL 事件組中列出了 DDL 觸發器的有效事件組。 ALTER TRIGGER 運行完成後,event_group 還將充當宏,將它涉及的事件類型添加到 sys.trigger_events 目錄視圖中。

{ [insert] [,] [update] [,] [delete] } { event_type [ ,...n ] | event_group }

--此屬性應用於DML觸發器的表和視圖

--指示當複製代理修改涉及到觸發器的表時,不該執行觸發器。
--not for replication

as
begin

  sql_statement;

end;

示例:本示例演示修改DML插入觸發器。

--聲明數據庫引用
use testss;
go

--修改觸發器
alter

--觸發器標識符
trigger

--DML觸發器所屬架構的名稱。 DML觸發器的做用域是爲其建立該觸發器的表或視圖的架構。不能爲DDL或登陸觸發器指定
--dbo觸發器名稱
dbo.inserttri

on

--對其執行DML觸發器的表或視圖,有時稱爲觸發器表或觸發器視圖。能夠根據須要指定表或視圖的徹底限定名稱。視圖只能被INSTEAD OF觸發器引用。不能對局部或全局臨時表定義DML觸發器。
dbo.test1

with
--此屬性適用於全部觸發器類型
--加密包含ALTER TRIGGER語句文本的sys.syscomments和sys.sql_modules項。使用WITH ENCRYPTION能夠防止將觸發器做爲SQL Server複製的一部分進行發佈。不能爲CLR觸發器指定WITH ENCRYPTION。
--encryption,

--指示觸發器已本機編譯。(只能應用於DML觸發器的table)
--內存優化表上的觸發器須要使用此選項。
--native_compilation,

--確保不能刪除或更改觸發器引用的表。(只能應用於DML觸發器的table)
--內存優化表上的觸發器須要使用此選項,但此選項不支持傳統表上的觸發器。
--schemabinding

--此屬性適用於全部觸發器類型
--{ EXEC | EXECUTE } AS { SELF | OWNER | 'user_name' }
--CALLER
--指定模塊內的語句在模塊調用方的上下文中執行。 執行模塊的用戶不只必須對模塊自己擁有適當的權限,還要對模塊引用的任何數據庫對象擁有適當權限。
--CALLER 是除隊列外的全部模塊的默認值,與 SQL Server 2005 行爲相同。
--CALLER 不能在 CREATE QUEUE 或 ALTER QUEUE 語句中指定。
--SELF
--EXECUTE AS SELF 與 EXECUTE AS user_name 等價,其中指定用戶是建立或更改模塊的用戶。 建立或更改模塊的用戶的實際用戶 ID 存儲在 sys.sql_modules 或 sys.service_queues 目錄視圖的 execute_as_principal_id 列中。
--SELF 是隊列的默認值。
--OWNER
--指定模塊內的語句在模塊的當前全部者上下文中執行。 若是模塊沒有指定的全部者,則使用模塊架構的全部者。 不能爲 DDL 或登陸觸發器指定 OWNER。
--' user_name '
--指定模塊內的語句在 user_name 指定的用戶的上下文中執行。 將根據 user_name 來驗證對模塊內任意對象的權限。 不能爲具備服務器做用域的 DDL 觸發器或登陸觸發器指定 user_name。 請改用 login_name。
--user_name 必須存在於當前數據庫中,而且必須是單一實例賬戶。 user_name 不能爲組、角色、證書、密鑰或內置賬戶,如 NT AUTHORITYLocalService、NT AUTHORITYNetworkService 或 NT AUTHORITYLocalSystem。
--執行上下文的用戶 ID 存儲在元數據中,能夠在 sys.sql_modules 或 sys.assembly_modules 目錄視圖的 execute_as_principal_id 列查看。
--內存優化表上的觸發器須要使用此選項。
execute as self

--FOR | AFTER
--AFTER 指定 DML 觸發器僅在觸發 SQL 語句中指定的全部操做都已成功執行時才被觸發。 全部的引用級聯操做和約束檢查也必須在激發此觸發器以前成功完成。
--若是僅指定 FOR 關鍵字,則 AFTER 爲默認值。
--不能對視圖定義 AFTER 觸發器。
for

--{ [DELETE] [,] [INSERT] [,] [UPDATE] }
--指定數據修改語句,這些語句可在 DML 觸發器對此表或視圖進行嘗試時激活該觸發器。 必須至少指定一個選項。 在觸發器定義中容許使用上述選項的任意順序組合。
--對於 INSTEAD OF 觸發器,不容許對具備指定級聯操做 ON DELETE 的引用關係的表使用 DELETE 選項。 一樣,也不容許對具備指定級聯操做 ON UPDATE 的引用關係的表使用 UPDATE 選項。
insert

--此屬性應用於DML觸發器的表和視圖
--指示當複製代理修改涉及到觸發器的表時,不該執行觸發器。
not for replication

as
begin
declare @sname nvarchar(100)=NULL,@sclassid int=NULL;
set @sname=(select name from inserted);
set @sclassid=(select classid from inserted);

--判斷是否須要向test插入name
if @sname is not null
begin
if(select id from dbo.test2 where name=@sname) is null
begin
insert into dbo.test2(name) values(@sname);
end;
end;

--判斷是否須要向test3插入classid
if @sclassid is not null
begin

if (select id from dbo.test3 where id=@sclassid) is not null
begin
print(@sclassid);
--insert into dbo.test1(name,sex,age,classid,height,xml1,xml2)
--select name,sex,age,classid,height,xml1,xml2 from inserted;
end;
end;
end;

示例結果:當向test1表中插入classid時,插入test3已存在的id時會打印1,插入test3不存在的id時不會打印1。

clipboard.png

clipboard.png

相關文章
相關標籤/搜索