SQL server 觸發器

一、什麼是觸發器?

  • 觸發器是在對錶進行插入、更新或刪除操作時自動執行的存儲過程
  • 觸發器通常用於強制業務規則
  • 觸發器是一種高級約束,可以定義比用CHECK 約束更爲複雜的約束
  • 可執行復雜的SQL語句(if/while/case)
  • 可引用其它表中的列

二、觸發器主要提供的功能

  • 在數據庫中的相關表上實現級聯更改
  • 事務功能,撤銷或回滾違反引用完整性的操作,防止非法修改操作
  • 執行比 CHECK 約束更復雜的約束操作
  • 在一張表的同一類型操作(update,insert,delete)上設置多個觸發器,從而可以對同樣的修改語句執行不同的多種操作。

三、使用觸發器的說明

  • 和特定表關聯,自動調用。
    • 當試圖在某個表插入、更新或刪除數據,而在那個表上定義了針對所做動作的觸發器,那麼觸發器會自動執行。
  • 只有表的擁有者纔可以在表上創建或刪除觸發器,這種權限不許轉授。
  • 不能再在視圖或臨時表上創建觸發器,但可以在觸發器中引用視圖或臨時表。
  • 是一個事務的部分。如果觸發器執行不成功,則整個修改事務回滾。
  • 不像普通的存儲過程,觸發器不能被直接調用,也不傳遞或接受參數,是自動調用的
  • 當使用約束、規則、默認值就可以實現預定的數據完整性時,應該優先使用前3種措施。

四、觸發器類型

  • DELETE 觸發器
  • INSERT 觸發器
  • UPDATE 觸發器
  • 觸發器觸發時:系統自動在內存中創建deleted表或inserted表只讀,不允許修改;觸發器執行完成後,自動刪除
  • inserted 表

    • 臨時保存了插入或更新後的記錄
    • 行可以從inserted表中檢查插入的數據是否滿足業務需求,如果不滿足,則向用戶報告錯誤消息,並回滾操作
  • deleted 表

    • 臨時保存了刪除或更新前的記錄行
    • 可以從deleted表中檢查被刪除的數據是否滿足業務需求, 如果不滿足,則向用戶報告錯誤消息,並回滾操作
修改操作 inserted表 deleted表
增加(INSERT)記錄 存放新增的記錄
刪除(DELETE)記錄 存放被刪除的記錄
修改(UPDATE)記錄 存放更新後的記錄 存放更新前的記錄

五、創建觸發器

創建觸發器的語法:

CREATE TRIGGER  trigger_name
 ON  table_name
 [WITH ENCRYPTION]
  FOR/AFTER/INSTEAD OF
     [DELETE, INSERT, UPDATE]
 AS 
  T-SQL語句
GO
--WITH ENCRYPTION表示加密觸發器定義的SQL文本
--DELETE, INSERT, UPDATE指定觸發器的類型

注意: SQL Server 不允許在觸發器中使用下列語句:
ALTER DATABASE、CREATE DATABASE、DISK INIT、DISK RESIZE、DROP DATABASE、LOAD DATABASE、LOAD LOG、RECONFIGURE、RESTORE DATABASE、RESTORE LOG

六、具體實例
一個典型的應用:銀行的取款系統
1.創建帳戶信息表bank和交易表transInfo

CREATE TABLE bank  --帳戶信息表
(
  customerName CHAR(8) NOT NULL,  --顧客姓名
  cardID  CHAR(10) NOT NULL ,       --卡號
  currentMoney MONEY  NOT NULL     --當前餘額
)
CREATE TABLE transInfo  --交易信息表
(
  cardID  CHAR(10) NOT NULL,    --卡號
  transType  CHAR(4) NOT NULL,  --交易類型(存入/支取)
  transMoney  MONEY NOT NULL,   --交易金額
  transDate  DATETIME NOT NULL, --交易日期
)

2.創建 INSERT 觸發器
當用戶想往銀行卡中存入或者支出的時候,就要向transInfo表中插入一條操作數據,此時,bank 表的currentMoney 餘額就應該根據操作類型進行相應的變化。

/*
創建一個transInfo 表的insert觸發器,當對transInfo 表進行插入操作的時候,就會調用該觸發器,將bank表中的餘額改掉
*/
CREATE TRIGGER trig_transInfo 
ON transInfo 
FOR INSERT 
   AS
   DECLARE @type char(4),@outMoney MONEY
   DECLARE @myCardID char(10),@balance MONEY
   SELECT @type=transType,@outMoney=transMoney,
         @myCardID=cardID FROM inserted --存放插入數據的臨時表
   IF (@type='支取') 
        UPDATE bank SET currentMoney=currentMoney-@outMoney WHERE cardID=@myCardID
   ELSE
      UPDATE bank SET currentMoney=currentMoney+@outMoney WHERE cardID=@myCardID
GO 

3.創建delete觸發器
當刪除交易信息表時,有時候需要備份要刪除的數據,創建觸發器,自動備份被刪除的數據到表backupTable中 。

/*在交易信息表上創建DELETE觸發器 
被刪除的數據可以從deleted表中獲取
*/
CREATE TRIGGER trig_delete_transInfo
 ON transInfo
  FOR DELETE 
   AS
      print '開始備份數據,請稍後......'
      IF NOT EXISTS(SELECT * FROM sysobjects 
           WHERE name='backupTable')
         SELECT * INTO backupTable FROM deleted
     ELSE
         INSERT INTO backupTable 
               SELECT * FROM deleted
      print '備份數據成功,備份表中的數據爲:'
      SELECT * FROM backupTable 
GO

4創建update觸發器
跟蹤用戶的交易,交易金額超過20000元,則取消交易,並給出錯誤提示,在bank表上創建UPDATE觸發器 ,修改前的數據可以從deleted表中獲取,修改後的數據可以從inserted表中獲取

CREATE TRIGGER trig_update_bank
 ON bank  FOR UPDATE
   AS
      DECLARE @beforeMoney MONEY,@afterMoney MONEY  
      --提示:update操作是將原有數據先刪除,然後重新插入數據。
      SELECT @beforeMoney=currentMoney FROM deleted   
      SELECT @afterMoney=currentMoney FROM inserted    
      IF ABS(@afterMoney-@beforeMoney)>20000 
        BEGIN
            print '交易金額:'+convert(varchar(8),
                ABS(@afterMoney-@beforeMoney))
           print '每筆交易不能超過2萬元,交易失敗'
            ROLLBACK TRANSACTION
         END
GO

UPDATE觸發器除了跟蹤數據的變化(修改)外,還可以檢查是否修改了某列的數據 ,使用UPDATE(列)函數檢測是否修改了某列

CREATE TRIGGER trig_update_transInfo
 ON transInfo
  FOR UPDATE
   AS
      IF UPDATE(transDate)
         BEGIN
            print '交易失敗.....'
            ROLLBACK TRANSACTION    
         END
GO 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章