2016-08-03 52 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