觸發器是一種特殊的存儲過程,它的執行不是由程序調用,也不是手動執行,而是由事件來觸發。觸發器是當對某一個表進行操做。例如:update、insert、delete這些操做的時候,系統會自動調用執行該表上對應的觸發器。sql
一、DML( 數據操縱語言 Data Manipulation Language)觸發器:是指觸發器在數據庫中發生 DML 事件時將啓用。DML事件是指在表或視圖中對數據進行的 insert、update、delete 操做的語句。數據庫
二、DDL(數據定義語言 Data Definition Language)觸發器:是指當服務器或數據庫中發生 DDL 事件時將啓用。DDL事件是指在表或索引中的 create、alter、drop 操做語句。安全
三、登錄觸發器:是指當用戶登陸 SQL SERVER 實例創建會話時觸發。若是身份驗證失敗,登陸觸發器不會觸發。服務器
其中 DML 觸發器比較經常使用,根據 DML 觸發器觸發的方式不一樣又分爲如下兩種狀況:測試
after 觸發器(以後觸發):其中 after 觸發器要求只有執行 insert、update、delete 某一操做以後觸發器纔會被觸發,且只能定義在表上。加密
instead of 觸發器 (以前觸發):instead of 觸發器並不執行其定義的操做(insert、update、delete)而僅是執行觸發器自己。能夠在表或視圖上定義 instead of 觸發器。3d
AFTER 觸發器語法:對象
CREATE [ OR ALTER ] TRIGGER [ schema_name . ]trigger_name ON { table } [ WITH <dml_trigger_option> [ ,...n ] ] { FOR | AFTER } { [ INSERT ] [ , ] [ UPDATE ] [ , ] [ DELETE ] } AS { sql_statement [ ; ] [ ,...n ] } <dml_trigger_option> ::= [ NATIVE_COMPILATION ] [ SCHEMABINDING ] [ EXECUTE AS Clause ]
INSTEAD OF 觸發器語法:blog
CREATE [ OR ALTER ] TRIGGER [ schema_name . ]trigger_name ON { table | view } [ WITH <dml_trigger_option> [ ,...n ] ] { FOR | AFTER | INSTEAD OF } { [ INSERT ] [ , ] [ UPDATE ] [ , ] [ DELETE ] } [ WITH APPEND ] [ NOT FOR REPLICATION ] AS { sql_statement [ ; ] [ ,...n ] | EXTERNAL NAME <method specifier [ ; ] > } <dml_trigger_option> ::= [ ENCRYPTION ] [ EXECUTE AS Clause ] <method_specifier> ::= assembly_name.class_name.method_name
DDL 觸發器語法:索引
CREATE [ OR ALTER ] TRIGGER trigger_name ON { ALL SERVER | DATABASE } [ WITH <ddl_trigger_option> [ ,...n ] ] { FOR | AFTER } { event_type | event_group } [ ,...n ] AS { sql_statement [ ; ] [ ,...n ] | EXTERNAL NAME < method specifier > [ ; ] } <ddl_trigger_option> ::= [ ENCRYPTION ] [ EXECUTE AS Clause ]
登錄觸發器語法:
CREATE [ OR ALTER ] TRIGGER trigger_name ON ALL SERVER [ WITH <logon_trigger_option> [ ,...n ] ] { FOR| AFTER } LOGON AS { sql_statement [ ; ] [ ,...n ] | EXTERNAL NAME < method specifier > [ ; ] } <logon_trigger_option> ::= [ ENCRYPTION ] [ EXECUTE AS Clause ]
參數介紹:
1. 建立AFTER INSERT 觸發器:當下單後更新tbOrderTotalPrice 的統計信息
準備一張訂單表(tbOrder),包含訂單ID,訂單交易金額,訂單建立時間,準備訂單交易分段時間總額(tbOrderTotalPrice ),用來統計每月的交易合計金額
USE [TEST] GO /****** Object: Trigger [dbo].[tSumTotalOrderPrice] Script Date: 2018/5/15 11:10:04 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TRIGGER [dbo].[tSumTotalOrderPrice] on [dbo].[tbOrder] AFTER INSERT AS BEGIN DECLARE @DT INT SET @DT= CONVERT(varchar(6),GETDATE(),112) DECLARE @SUM DECIMAL(18, 2) SET @SUM=(SELECT SUM(OPrice) FROM tbOrder WHERE @DT = CONVERT(varchar(6),CreateDT,112)) IF(EXISTS(SELECT * FROM tbOrderTotalPrice WHERE YearMoth=@DT)) BEGIN UPDATE tbOrderTotalPrice SET TotalPrice=@SUM WHERE YearMoth=@DT END ELSE BEGIN INSERT INTO tbOrderTotalPrice VALUES (@DT,@SUM) END END GO
執行INSERT 行爲:INSERT INTO [dbo].[tbOrder]([OPrice],[CreateDT])VALUES(9,GETDATE())
2.建立 instead of insert 觸發器,當添加用戶成績記錄時候,驗證學號和學科存在才能進行添加操做
準備學生表(tbStudent),學科表(tbSubject),成績表(tbStuSubScore)
在學生表中添加測試學生,在學科標準添加測試學科
新增instead of insert 觸發器,在執行INSERT 語句前驗證學號和學科存在才能進行添加操做
USE [TEST] GO /****** Object: Trigger [dbo].[tCheckStuSubScore] Script Date: 2018/5/17 14:20:53 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO -- ============================================= -- Author: yangyi -- Create date: 2018/5/17 -- Description: 新增學科分數 -- ============================================= CREATE TRIGGER [dbo].[tCheckStuSubScore] ON [dbo].[tbStuSubScore] INSTEAD OF INSERT AS BEGIN --驗證學號是否存在 IF(NOT EXISTS(SELECT * FROM tbStudent WHERE StuID=(SELECT StuID FROM inserted))) BEGIN PRINT('驗證學號不否存在') ROLLBACK TRANSACTION END ELSE BEGIN --驗證學科是否存在 IF(NOT EXISTS(SELECT * FROM tbSubject WHERE SubID=(SELECT SubID FROM inserted))) BEGIN PRINT('驗證學科不否存在') ROLLBACK TRANSACTION END ELSE BEGIN --執行INSERT INSERT INTO tbStuSubScore SELECT * FROM inserted END END END GO
注意:
在觸發器語句中用兩個特殊的表一個是deleted表和inserted。它們是經過觸發器操做自動建立駐留在內存中的臨時表。
Deleted表用於存儲 DELETE和 UPDATE語句所影響的行的複本。在執行DELETE或 UPDATE語句時,行從觸發器表中刪除,並傳輸到 deleted表中。Deleted表和觸發器表一般沒有相同的行。
Inserted 表用於存儲 INSERT 和 UPDATE 語句所影響的行的副本。在一個插入或更新事務處理中,新建行被同時添加到 inserted 表和觸發器表中。Inserted 表中的行是觸發器表中新行的副本
1.插入操做(Insert) Inserted表有數據,Deleted表無數據
2.刪除操做(Delete) Inserted表無數據,Deleted表有數據
3.更新操做(Update) Inserted表有數據(新數據),Deleted表有數據(舊數據)
測試:
1>.執行INSERT 添加一條學科不存不正常在的學生成績記錄,執行失敗
INSERT INTO [dbo].[tbStuSubScore]([StuID],[Score],[SubID],[CreateDT])VALUES('001',100,0,GETDATE())
2.>執行INSERT 添加一條學號不存不正常在的學生成績記錄,執行失敗
INSERT INTO [dbo].[tbStuSubScore]([StuID],[Score],[SubID],[CreateDT])VALUES('004',100,1,GETDATE())
3.>執行一條正常的學生成績記錄,執行成功
INSERT INTO [dbo].[tbStuSubScore]([StuID],[Score],[SubID],[CreateDT])VALUES('001',100,1,GETDATE())