萬盛學電腦網

 萬盛學電腦網 >> 數據庫 >> mssql數據庫 >> SQLServerDML觸發器之AFTER觸發器

SQLServerDML觸發器之AFTER觸發器

   根據DML觸發器發生的時間、編寫觸發器所使用的語言,可以分為AFTER觸發器、INSTEAD OF觸發器和CLR觸發器。AFTER觸發器在執行INSERT、UPDATE或DELETE語句操作之後、INSTEAD OF觸發器和約束之後激發。INSTEAD OF在處理約束前激發,因此可以在INSTEAD OF中使用其他語句來替代激發觸發器的INSERT、UPDATE等語句。並且,還可為基於一個或多個基表的視圖定義INSTEAD OF觸發器,從而擴展視圖可支持的更新類型。CLR觸發器可以是AFTER觸發器或INSTEAD OF觸發器,並且也可以是DDL觸發器。

  需要注意的是,在創建DML觸發器時,不能使用下列語句:

  ALTER DATABASE CREATE DATABASE DROP DATABASE

  LOAD DATABASE LOAD LOG RECONFIGURE

  RESTORE DATABASE RESTORE LOG

  14.1.1 AFTER觸發器

  一個表中可以具有多個AFTER觸發器,只要它們的名稱不相同即可。每個觸發器只能應用於一個表,但是一個觸發器可以同時應用於一個表的三個用戶操作(UPDATE、INSERT和DELETE)。

  下面的語句創建了一個PriTrigger表和一個DetailTable,其中PriTrigger表用於存放銷售訂單的編號和金額,DetailTable表用於存放每筆訂單中的產品信息。為PriTrigger表的DELETE操作創建了一個名為PriTrigger的觸發器,當刪除PriTrigger表中的訂單信息時,該觸發器將刪除DetailTable表中該筆訂單的產品信息。

  USE AdventureWorks;

  GO

  -- 創建主表,存放銷售訂單編號和金額

  CREATE TABLE PriTable

  (OrderID int IDENTITY(1,1), OrderTotal money);

  GO

  -- 創建明細表,存放每筆訂單中的產品信息

  CREATE TABLE DetailTable

  (OrderID int, ProductID int, ProductCount int NOT NULL, Price money);

  GO

  -- 向主表中插入訂單信息

  INSERT INTO PriTable VALUES (2100.00);

  INSERT INTO PriTable VALUES (1000.00);

  -- 向明細表中插入訂單的產品信息

  INSERT INTO DetailTable VALUES (1,1,10,110.00);

  INSERT INTO DetailTable VALUES (1,2,10,100.00);

  INSERT INTO DetailTable VALUES (2,2,10,100.00);

  GO

  -- 為PriTrigger表創建觸發器

  CREATE TRIGGER PriTrigger

  ON PriTable

  AFTER DELETE

  AS

  DELETE FROM DetailTable

  WHERE OrderID IN (SELECT OrderID

  FROM Deleted);

  PRINT N'已經刪除了DetailTable表中的相關數據' -- 此句僅為演示需要,在觸發器中不應當使用這樣的信息語句

  在定義觸發器時,觸發器名稱在CREATE TRIGGER關鍵字之後,ON子句指定要創建觸發器的基表。AFTER子句(也可以使用FOR來代替AFTER關鍵字,二者功能相同)指定激活觸發器的操作語句,可以同時指定多個操作語句。例如,“AFTER DELETE, INSERT”表示在對表執行DELETE、INSERT語句時激活觸發器。AS關鍵字後指定觸發器執行什麼樣的操作。

  注意WHERE條件中IN子句中的Deleted關鍵字。當從PriTrigger表中刪除行時,被刪除的行會被復制到一個名為Deleted的臨時內存表中。如果為表指定了一個執行INSERT語句時的觸發器,則在向表中插入行時,新行將同時被添加到一個名為Inserted的臨時內存表中。如果為表指定了一個執行UPDATE語句時的觸發器,由於更新事務類似於在刪除操作之後執行插入操作。因此,舊行被復制到Deleted表中,然後,新行被復制到觸發器表和Inserted表中。

  Deleted表和Inserted表都是由SQL Server自動創建和管理的,這些表的結構與定義觸發器的基表的結構相同。

  執行下面的語句從PriTable表中刪除OrderID為1的行,這時觸發器會自動刪除DetailTable表中的相關行,得到的結果和消息如圖14-1所示。

  DELETE FROM PriTable WHERE OrderID = 1;

  SELECT * FROM PriTable;

  SELECT * FROM DetailTable;

SQLServerDML觸發器之AFTER觸發器   三聯

  圖14-1 刪除PriTable表中OrderID為1的行時得到的結果和消息

  如果執行下面的語句,准備從PriTable表中刪除OrderID為3的行。由於PriTable表中並不存在這樣的行,所以並不會刪除成功。雖然沒有刪除成功,但是在消息窗口中仍然可以看到由觸發器的PRINT語句發回的信息。這說明即使語句沒有影響到表中的行,也會激活觸發器。在沒有刪除成功的情況下,Deleted表是一個空表。

  DELETE FROM PriTable WHERE OrderID = 3;

copyright © 萬盛學電腦網 all rights reserved