2016-08-03 20 views
1

我有以下情形:如何使在主從觸發器

CREATE TABLE dbo.Orders 
( 
    OrderID int IDENTITY (1,1) NOT NULL 
    , OrderVersion int DEFAULT(1) 
    , Customer varchar(30) 
    , ScheduleDate date 
    , PaymentOption int 
); 

CREATE TABLE dbo.OrdersItems 
( 
    OrderItemsID int IDENTITY (1,1) NOT NULL 
    , OrderID int 
    , Product varchar(100) 
    , Qty  int 
    , value decimal(18,2) 
); 

CREATE TABLE dbo.logOrders 
( 
    OrderID int NOT NULL 
    , OrderVersion int DEFAULT(1) 
    , Customer varchar(30) 
    , ScheduleDate date 
    , PaymentOption int 
); 

CREATE TABLE dbo.logOrdersItems 
( 
    OrderItemsID int NOT NULL 
    , OrderID int 
    , Product varchar(100) 
    , Qty  int 
    , value decimal(18,2) 
); 

-- Insert values into the table. 
INSERT INTO dbo.Orders (Customer , ScheduleDate, PaymentOption) 
VALUES ('John', 2016-09-01, 1); 

INSERT INTO dbo.OrdersItems(OrderId, Product, Qty, Value) 
VALUES (1, 'Foo', 20, 35.658), 
     (1, 'Bla', 50, 100) 
     (1, 'XYZ', 10, 3589) 

首先聲明

UPDATE Orders set ScheduleDate = 2016-10-05 WHERE OrderId = 1 

第二條語句

Delete From OrdersItems WHERE OrderItemsID = 2 
UPDATE OrdersItems set Qty = 5 WHERE OrderItemsID = 1 

第三條語句

Update Orders set PaymentOption = 2 WHERE OrderId = 1 
Update OrdersItems set Value = 1050 WHERE OrderItemsID = 3 

我想弄清楚如何做一個觸發器,在上面的每個語句樣例之後在更改之前在日誌表上插入數據。在訂單表上將OrderVersion設置爲OrderVersion + 1。 所以在日誌表中,我會在後面的所有版本之後。

是否有可能在UPDATE,DELETE,INSERT語句之前使用單個觸發器來監視兩個表並執行獲取原始數據以獲取原始數據並在logTables上執行INSERT操作?

這裏有一個示例來更好地解釋我想要的結果。

This is the Initial Data on table Orders and OrdersItems

如果我做的訂單(所有列)的更新或進行更新,插入,刪除上OrdersItems我需要分別插入上logTables的圖像數據。 然後,我將在logOrders和logItems上顯示原始數據以及訂單和項目中已更改的數據。

我希望我能更好地解釋我的意思。

+1

你可以達到你想要的東西通過觸發器(對數表改變之前的數據插入),但是你的要求是不夠清楚,可以請你帶一些樣品解釋,並用它解釋一起,包括預期的結果 – TheGameiswar

+0

只能爲單個表指定dml觸發器。但是,您可以爲每個將處理更新,刪除和插入的表創建一個觸發器。 –

回答

0

您將需要兩個觸發器。訂單表的觸​​發器處理訂單表更新/刪除。 OrdersItems表的觸發器對OrdersItems也是如此。觸發器是這樣的:

Orders表:

CREATE TRIGGER dbo.Orders_trigger 
    ON dbo.Orders 
    AFTER DELETE,UPDATE 
AS 
BEGIN 
    SET NOCOUNT ON; 

    INSERT INTO dbo.logOrders 
    SELECT * FROM DELETED; 

    INSERT INTO dbo.logOrdersItems 
    SELECT oi.* FROM OrdersItems oi 
    WHERE oi.OrderID IN (SELECT OrderId FROM DELETED); 

END 
GO 

對於OrdersItems:

CREATE TRIGGER dbo.OrdersItems_trigger 
    ON dbo.OrdersItems 
    AFTER DELETE,UPDATE 
AS 
BEGIN 
    SET NOCOUNT ON; 

    --Inerst the changed/deleted OrdersItems into the log 
    INSERT INTO dbo.logOrdersItems 
    SELECT * FROM DELETED 

    --Inserts the unchanged sibling OrdersItems records into the log 
    INSERT INTO dbo.logOrdersItems 
    SELECT oi.* FROM OrdersItems oi 
    WHERE oi.OrderId IN (SELECT DISTINCT OrderId FROM DELETED) 
    AND oi.OrderItemsID NOT IN (SELECT DISTINCT OrderItemsID FROM DELETED); 

    INSERT INTO dbo.logOrders 
    SELECT o.* FROM Orders o 
    WHERE o.OrderID IN (SELECT DISTINCT OrderId FROM DELETED); 

END 
GO 

的訂單觸發相當簡單。使用虛擬DELETED表將原始版本的記錄插入到日誌中。然後加入OrdersItems記錄並將它們插入日誌中。這樣寫的方式,即使您一次更新或刪除多個訂單記錄,它也可以工作。

OrdersItems觸發器有點複雜。您需要記錄OrdersItems和訂單記錄的預先版本。但你也想(我認爲)記錄未改變的「兄弟」OrdersItems記錄,以便你有一個完整的記錄圖片。

我知道這只是您的示例數據,但您需要爲日誌表中的記錄添加某種時間戳。否則,你只會得到一堆重複的行,你不知道哪個是哪個。在觸發器開始時,您可以創建一個變量來保存更新日期時間,然後將其附加到日誌的INSERT語句中。

DECLARE @UpdateDateTime DATETIME; 
SET @UpdateDateTime = GETUTCDATE(); 
+0

@JeanSilvaPaulo只是迴旋。這是否解決了你的問題? – MattPerry