在触发器中查找多个更新列

时间:2014-06-25 12:00:40

标签: sql-server triggers sql-server-2008-r2 sql-server-2012

我需要在表中标识多个列更新并将它们存储在Audit表中 这是审计架构:

 auditid   auditTimestamps updateFieldName  oldFieldValue  newFieldValue

我们有另一个具有架构的表员工:

  EmpID  EmpName  Age  Address1  Phone

我在员工架构上写了更新触发器,当记录更新时,触发器被触发并在触发器上检查哪个字段值已更新并在审计表架构上维护此信息。

 For checking field for update , i have used below code sample:

    BEGIN 
           if update(empName)
           begin 
              set @updatedcolumnname='empName';
              set @newvendorname=(SELECT empNameFROM inserted);
              set @oldvendorname=(SELECT empNameFROM deleted);
              //Here insert logic that insert above find values into audit table.
            end

              // Same check for all remaining fields( Age,Address1,Phone) 
   END

但它似乎不适合我。它会插入所有更新但未更新到审计表中的列。

请建议如何在功能上实现以上功能。

由于

1 个答案:

答案 0 :(得分:0)

您可以在触发器中使用merge命令而不是insert命令。您还可以通过以下查询计算更改的列:

SELECT 'empName' AS FieldName, d.empName AS OldValue, i.empName AS NewValue
FROM Inserted i
INNER JOIN deleted d ON d.EmpID = i.EmpID  
WHERE i.EmpName<>d.ImpName

UNION ALL

SELECT 'Age', d.Age, i.Age
FROM Inserted i
INNER JOIN deleted d ON d.EmpID = i.EmpID
WHERE i.Age<>d.Age

UNION ALL

SELECT 'Address1', d.Address1, i.Address1
FROM Inserted i
INNER JOIN deleted d ON d.EmpID = i.EmpID
WHERE i.Address1<>d.Address1

UNION ALL

SELECT 'Phone', d.Phone, i.Phone
FROM Inserted i
INNER JOIN deleted d ON d.EmpID = i.EmpID
WHERE i.Phone<>d.Phone

所以你的查询:

MERGE AuditTable AS Destination
USING (
        SELECT 'empName' AS FieldName, d.empName AS OldValue, i.empName AS NewValue
        FROM Inserted i
        INNER JOIN deleted d ON d.EmpID = i.EmpID
        WHERE i.EmpName<>d.ImpName

        UNION ALL

        SELECT 'Age', d.Age, i.Age
        FROM Inserted i
        INNER JOIN deleted d ON d.EmpID = i.EmpID
        WHERE i.Age<>d.Age

        UNION ALL

        SELECT 'Address1', d.Address1, i.Address1
        FROM Inserted i
        INNER JOIN deleted d ON d.EmpID = i.EmpID
        WHERE i.Address1<>d.Address1

        UNION ALL

        SELECT 'Phone', d.Phone, i.Phone
        FROM Inserted i
        INNER JOIN deleted d ON d.EmpID = i.EmpID
        WHERE i.Phone<>d.Phone

    ) AS SOURCE ON SOURCE.FieldName = Destination.UpdateFieldName 
                AND SOURCE.OldValue = Destination.OldFieldValue
                AND SOURCE.NewValue = Destinatino.NewFieldValue
    WHEN MATCHED THEN UPDATE SET OldFieldValue  = OldValue,
                                NewFieldValue = NewValue
    WHEN NOT MATCHED THEN INSERT (UpdateFieldName, OldFieldValue, NewFieldValue) 
                        VALUES(FieldName, OldValue,NewValue)