用SQL Server觸發器實現業務規則的強制執行

iSQlServer發表於2009-02-01
Microsoft SQL Server 2000 提供了兩種主要機制來強制業務規則和資料完整性:約束和觸發器。

  觸發器是一種特殊型別的儲存過程,它在指定的表中的資料發生變化時自動生效。喚醒呼叫觸發器以響應 INSERT、UPDATE 或 DELETE 語句。觸發器可以查詢其它表,並可以包含複雜的 Transact-SQL 語句。將觸發器和觸發它的語句作為可在觸發器內回滾的單個事務對待。如果檢測到嚴重錯誤(例如,磁碟空間不足),則整個事務即自動回滾。

  觸發器的優點如下:

  觸發器可通過資料庫中的相關表實現級聯更改;不過,通過級聯引用完整性約束可以更有效地執行這些更改。

  觸發器可以強制比用 CHECK 約束定義的約束更為複雜的約束。與 CHECK 約束不同,觸發器可以引用其它表中的列。例如,觸發器可以使用另一個表中的 SELECT 比較插入或更新的資料,以及執行其它操作,如修改資料或顯示使用者定義錯誤資訊。觸發器也可以評估資料修改前後的表狀態,並根據其差異采取對策。一個表中的多個同類觸發器(INSERT、UPDATE 或 DELETE)允許採取多個不同的對策以響應同一個修改語句。

  觸發器與約束的比較

  約束和觸發器在特殊情況下各有優勢。觸發器的主要好處在於它們可以包含使用 Transact-SQL 程式碼的複雜處理邏輯。因此,觸發器可以支援約束的所有功能;但它在所給出的功能上並不總是最好的方法。

  實體完整性總應在最低階別上通過索引進行強制,這些索引或是 PRIMARY KEY 和 UNIQUE 約束的一部分,或是在約束之外獨立建立的。假設功能可以滿足應用程式的功能需求,域完整性應通過 CHECK 約束進行強制,而引用完整性 (RI) 則應通過 FOREIGN KEY 約束進行強制。

  在約束所支援的功能無法滿足應用程式的功能要求時,觸發器就極為有用。例如:

  除非 REFERENCES 子句定義了級聯引用操作,否則 FOREIGN KEY 約束只能以與另一列中的值完全匹配的值來驗證列值。

  CHECK 約束只能根據邏輯表示式或同一表中的另一列來驗證列值。如果應用程式要求根據另一個表中的列驗證列值,則必須使用觸發器。

  約束只能通過標準的系統錯誤資訊傳遞錯誤資訊。如果應用程式要求使用(或能從中獲益)自定義資訊和較為複雜的錯誤處理,則必須使用觸發器。

  觸發器可通過資料庫中的相關表實現級聯更改;不過,通過級聯引用完整性約束可以更有效地執行這些更改。

  觸發器可以禁止或回滾違反引用完整性的更改,從而取消所嘗試的資料修改。當更改外來鍵且新值與主鍵不匹配時,此類觸發器就可能發生作用。例如,可以在 titleauthor.title_id 上建立一個插入觸發器,使它在新值與 titles.title_id 中的某個值不匹配時回滾一個插入。不過,通常使用 FOREIGN KEY 來達到這個目的。

  如果觸發器表上存在約束,則在 INSTEAD OF 觸發器執行後但在 AFTER 觸發器執行前檢查這些約束。如果約束破壞,則回滾 INSTEAD OF 觸發器操作並且不執行 AFTER 觸發器。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/16436858/viewspace-544960/,如需轉載,請註明出處,否則將追究法律責任。

相關文章