top
Loading...
如何使用SQLServerINSTEAD-OF觸發器

觸發器是類似于存儲程序的數據庫對象,它響應數據庫環境下的某個請求。SQL Sever 2005包含3個觸發器對象:AFTER,數據定義語言 (DDL)和INSTEAD-OF。

AFTER觸發器是存儲程序,它發生于數據操作語句作用之后,例如刪除語句等。DDL是SQL Server 2005的新觸發器,允許響應數據庫引擎中對象定義水平事件(例如:DROP TABLE語句)。INSTEAD-OF觸發器是對象,在數據庫引擎中可以取代數據操作語句而執行。例如:將INSTEAD-OF INSERT觸發器附加到表,告訴數據庫執行此觸發器。

使用INSTEAD-OF觸發器的理由

INSTEAD-OF觸發器是SQL Sever功能強大的對象,允許開發人員轉移數據庫引擎完成不同的工作,以滿足開發要求。其中的一個例子是在數據庫的表中添加INSTEAD-OF觸發器,當不需要修改表時,可以對表的內容進行回滾。使用此方法時,必須格外小心,因為任何指定的表修改之前,INSTEAD-OF觸發器必須處于激活狀態。

使用INSTEAD-OF觸發器一個更充分理由是視圖處理。在視圖中添加INSTEAD-OF觸發器后,則可創建更新的視圖。可更新視圖允許完整地提取數據庫大綱,因此可以用此方法設計系統,而不需要擔心OLTP數據庫大綱的問題,并且取代數據修改一組標準視圖集。

范例

Listing A CREATE TABLE Products(      ProductID SMALLINT IDENTITY(1,1) PRIMARY KEY,      Description VARCHAR(75),      Price MONEY NOT NULL)GOCREATE TABLE Purchases(      PurchaseID SMALLINT IDENTITY(1,1) PRIMARY KEY,      ProductID SMALLINT REFERENCES Products(ProductID),      PurchasePrice MONEY NOT NULL,       PurchaseDate SMALLDATETIME DEFAULT(GETDATE()))

為了更好地說明可更新視圖概念,我們提供一個示例。在本例中,我們設計一個產品表(記錄產品),一個購買表(記錄購買)。Listing A包含了創建表的腳本,運行此腳本后則得到示例中所要用到的表。運行Listing B腳本向表中添加數據。

Listing BINSERT INTO Products(Description, Price) VALUES('Television',500)INSERT INTO Products(Description, Price) VALUES('VCR',100)INSERT INTO Products(Description, Price) VALUES('DVD_Player',125)INSERT INTO Products(Description, Price) VALUES('Alarm_Clock',40)INSERT INTO Products(Description, Price) VALUES('Camera',325)INSERT INTO Products(Description, Price) VALUES('Projector',1500)INSERT INTO Products(Description, Price) VALUES('XBox',400)GOINSERT INTO Purchases(ProductID, PurchasePrice) VALUES(1, 500)INSERT INTO Purchases(ProductID, PurchasePrice) VALUES(5, 325)INSERT INTO Purchases(ProductID, PurchasePrice) VALUES(1, 525)GO

現在表中已經有數據了,我可以為這些表創建一些有意義的視圖。請查看Listing C。

isting CCREATE VIEW vw_ProductPurchasesAS      SELECT            pr.ProductID,             pr.Description,             pr.Price AS ProductPrice,             pu.PurchasePrice,             pu.PurchaseDate         FROM            Products pr            INNER JOIN Purchases pu ON pr.ProductID = pu.ProductIDGO

這是個典型的產品水平的視圖。它聯合了數據庫中的兩個表,使得數據簡單化了。但是,對于數據提取,使用視圖則沒有什么優勢。在視圖上附上INSTEAD-OF觸發器后,則允許修改表,但是我不需要直接修改表中的數據。我使用Listing D中的代碼在vw_ProductPurchases視圖上創建一個INSTEAD-OF觸發器。

Listing DCREATE TRIGGER tr_vwProductPurchases ON vw_ProductPurchasesINSTEAD OF INSERTASBEGIN      IF EXISTS      (            SELECT TOP 1 *            FROM INSERTED            WHERE                   ProductID IS NOT NULL AND                  ISNULL(COALESCE(PurchasePrice, ProductPrice),0)>0      )      BEGIN            INSERT INTO Purchases            (                  ProductID, PurchasePrice, PurchaseDate            )            SELECTi.ProductID, COALESCE(PurchasePrice, ProductPrice), ISNULL(PurchaseDate, GETDATE())            FROM INSERTED i         END      ELSE      BEGIN            PRINT 'Adequate data not provided.'      ENDEND

請注意此INSTEAD OF觸發器的聲明。SQL Server創建的默認的觸發器為AFTER觸發器,因此,必須在觸發器定義中指定INSTEAD OF子句。

觸發器的第一條語句是“check”語句。本例中我使用此語句檢測INSERTED表以確保顯示ProductID字段,并且保證提供顯示其他PurchasePrice 或 ProductPrice字段。

如果必要的數據通過INSERT語句都插入到視圖中,則觸發器將插入指定的值到數據表。下面即是視圖的INSERT語句。 INSERT INTO vw_ProductPurchases(ProductID, PurchasePrice) VALUES(1, 700)

INSERT語句提供了有效的ProductID和PurchasePrice,這意味著新記錄插入到Purchases表。

結論

INSTEAD-OF觸發器具有強大的功能和靈活性。如果系統不大,使用視圖系統提取數據大綱能夠極大保護數據庫程序。

上面的例子很簡單,系統中所用到的復雜的觸發器需要考慮安全性問題、時間開銷和其他限制。

Tim Chapman是一個 SQL Server數據庫管理員,他在Louisville, KY的一家銀行工作,有7年的IT工作經驗,通過了微軟SQL Server 2000 和SQL Server 2005認證。

(T114)

作者:http://www.zhujiangroad.com
來源:http://www.zhujiangroad.com
北斗有巢氏 有巢氏北斗