简体   繁体   中英

I am looking for a way for a trigger to insert into a second table only where the value in table 1 changes

I am looking for a way for a trigger to insert into a second table only where the value in table 1 changes. It is essentially an audit tool to trap any changes made. The field in table 1 is price and we want to write additional fields.

This is what I have so far.

CREATE  TRIGGER zmerps_Item_costprice__update_history_tr ON [ITEM] 
FOR UPDATE
AS
insert into zmerps_Item_costprice_history
        select  NEWID(), -- unique id
                GETDATE(),  -- CURRENT_date
                'PRICE_CHANGE', -- reason code
                a.ima_itemid, -- item id
                a.ima_price-- item price

            FROM  Inserted b inner join item a
                    on b.ima_recordid = a.IMA_RecordID

The table only contains a unique identifier, date, reference(item) and the field changed (price). It writes any change not just a price change

Is it as simple as this? I moved some of the code around because comments after the comma between columns is just painful to maintain. You also should ALWAYS specify the columns in an insert statement. If your table changes this code will still work.

CREATE  TRIGGER zmerps_Item_costprice__update_history_tr ON [ITEM] 
FOR UPDATE
AS
insert into zmerps_Item_costprice_history
(
    UniqueID
    , CURRENT_date
    , ReasonCode
    , ItemID
    , ItemPrice
)
    select  NEWID()
        , GETDATE()
        , 'PRICE_CHANGE'
        , d.ima_itemid
        , d.ima_price
    FROM Inserted i 
    inner join deleted d on d.ima_recordid = i.IMA_RecordID
        AND d.ima_price <> i.ima_price

Since you haven't provided any other column names I Have used Column2 and Column3 and the "Other" column names in the below example.

You can expand adding more columns in the below code.

overview about the query below:

Joined the deleted and inserted table (only targeting the rows that has changed) joining with the table itself will result in unnessacary processing of the rows which hasnt changed at all.

I have used NULLIF function to yeild a null value if the value of the column hasnt changed.

converted all the columns to same data type (required for unpivot) .

used unpivot to eliminate all the nulls from the result set.

unpivot will also give you the column name its has unpivoted it.

CREATE  TRIGGER zmerps_Item_costprice__update_history_tr 
ON [ITEM] 
FOR UPDATE
AS 
BEGIN
  SET NOCOUNT ON ;

WITH CTE AS (
SELECT  CAST(NULLIF(i.Price   , d.Price)    AS NVARCHAR(100)) AS Price
       ,CAST(NULLIF(i.Column2 , d.Column2)  AS NVARCHAR(100)) AS Column2
       ,CAST(NULLIF(i.Column3 , d.Column3)  AS NVARCHAR(100)) AS Column3
FROM dbo.inserted i 
INNER JOIN dbo.deleted d ON i.IMA_RecordID = d.IMA_RecordID
WHERE i.Price   <> d.Price
 OR   i.Column2 <> d.Column2
 OR   i.Column3 <> d.Column3
 )
 INSERT INTO zmerps_Item_costprice_history
               (unique_id, [CURRENT_date], [reason code], Item_Value)
 SELECT  NEWID()
        ,GETDATE()
        ,Value
        ,ColumnName + '_Change'
 FROM CTE UNPIVOT (Value FOR ColumnName IN (Price , Column2, Column3) )up

END

As I understand your question correctly, You want to record change If and only if The column Price value is changes, you dont need any other column changes to be recorded

here is your code

CREATE  TRIGGER zmerps_Item_costprice__update_history_tr ON [ITEM] 
FOR UPDATE
AS
if update(ima_price)
insert into zmerps_Item_costprice_history
    select  NEWID(), -- unique id
            GETDATE(),  -- CURRENT_date
            'PRICE_CHANGE', -- reason code
            a.ima_itemid, -- item id
            a.ima_price-- item price

        FROM  Inserted b inner join item a
                on b.ima_recordid = a.IMA_RecordID

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM