2016-12-27 12 views
0

価格変更に関する情報を別のテーブルに挿入するトリガーを作成する必要があります。私は私の解決策を以下に示します。テーブル更新に関するログ情報を含むトリガーを作成

CREATE TABLE Production.Products_AUDIT 
(
    auditid  INT   NOT NULL IDENTITY, 
    productid INT   NULL, 
    old_price MONEY  NOT NULL, 
    new_price MONEY  NOT NULL, 

    CONSTRAINT PK_Products_AUDIT PRIMARY KEY(auditid), 
    CONSTRAINT FK_Products_AUDIT_AUDIT 
     FOREIGN KEY(productid) REFERENCES Production.Products(productid) 
); 

INSERT INTO Production.Products_AUDIT VALUES (1, 18 , 20) 
INSERT INTO Production.Products_AUDIT VALUES (2, 19 , 31) 

DELETE FROM Production.Products_AUDIT 

SELECT unitprice 
FROM Production.Products_AUDIT as p1 
INNER JOIN Production.Products as p2 on p1.productid = p2.productid 

CREATE TRIGGER trig1 
ON Production.Products 
FOR UPDATE 
AS 
    declare @prodId INT 
    declare @oldPrice MONEY 
    declare @newPrice MONEY 

    SET @prodId = (SELECT i.productid 
        FROM inserted as i 
        INNER JOIN Production.Products as pp on i.productid = pp.productid) 
    SET @oldPrice = (SELECT i.unitprice 
        FROM deleted as i 
        INNER JOIN Production.Products as pp on i.productid = pp.productid) 

    SET @newPrice = (SELECT i.unitprice 
        FROM inserted as i 
        INNER JOIN Production.Products as pp on i.productid = pp.productid) 

    INSERT INTO Production.Products_AUDIT 
    VALUES(@prodId, @oldPrice, @newPrice) 

    UPDATE Production.Products 
    SET unitprice = 45 
    WHERE productid < 2 

    SELECT * FROM Production.Products_AUDIT 

1つのレコードのみを更新しても問題ありません。サブクエリが複数の値を返し

メッセージ512、レベル16、状態1、プロシージャTRIG1、ライン41
:問題は、私は多くのレコードを更新しようとすると、その後、私は下のエラーが表示されます。 =、!=、<、< =、>、> =、またはサブクエリが式として使用されている場合は、これは許可されません。 ステートメントが終了しました。

誰でもこの問題を解決する方法は知っていますか?

+0

@XINGいいえ、それは特にトリガーでは悪い考えです。セットベースのアプローチが必要です。 –

答えて

2

トリガーは、行ベースではなく、ステートメントベースで起動されるという問題があります。つまり、ステートメントで更新されたすべての行に対してトリガーが1回実行されるため、inserteddeletedの表に複数の行が含まれる可能性があります。

ただし、トリガーコードで考慮されていないため、エラーが発生します。

が、この代わりに試してみてください:

CREATE TRIGGER Products_ForUpdate 
ON Production.Products 
FOR UPDATE 
AS 

    INSERT INTO Production.Products_AUDIT 
    SELECT i.productid, d.unitprice, i.unitprice 
    FROM inserted as i 
    INNER JOIN Production.Products as pp on i.productid = pp.productid 
    INNER JOIN deleted as d ON pp.productid = d.productid 
2

トリガーは、UPDATE文で行ごとではないUPDATEステートメントごとに発射されます。あなたは........ちょうどinserteddeletedテーブルからデータ(新旧)のデータを選択して、直接監査テーブルにこのような何かを、それを挿入し、すべてのこれらの変数のいずれかを必要としない

CREATE TRIGGER trig1 
ON Production.Products 
FOR UPDATE 
as 
BEGIN 
SET NOCOUNT ON; 

    INSERT INTO Production.Products_AUDIT (productid , Old_Price , New_Price) 
    SELECT pp.productid 
     , d.unitprice AS OldPrice 
     , i.unitprice AS NewPrice 
    FROM Production.Products as pp 
    INNER JOIN inserted i ON i.productid = pp.productid 
    INNER JOIN deleted d ON d.productid = pp.productid 

END 
+0

ありがとうございます。すべて素晴らしいです。 –

関連する問題