SQL Server:为审计/历史记录表创建触发器

时间:2017-03-06 23:16:34

标签: sql sql-server triggers

我正在创建我的第一个SQL Server触发器,并希望插入到"历史记录"表插入另一个表后。我想我已经编写了大部分代码,但似乎无法完成语法。当前格式表明" HistoryColumnName"和" HistoryNewValue"无效。我已经尝试了一个JOIN到变量表@HistoryRecord,但它并不真正有意义,因为它们是独立的。

以下代码:

CREATE TRIGGER CreateHardwareAssetHistoryRecord
ON HardwareAsset
AFTER INSERT AS

DECLARE
@HardwareAssetID UNIQUEIDENTIFIER,
@HardwareAssetTitle VARCHAR(256),
@HardwareAssetSerialNumber VARCHAR(256)
SET @HardwareAssetID = (SELECT HardwareAssetID FROM inserted)
SET @HardwareAssetTitle = (SELECT HardwareAssetTitle FROM inserted)
SET @HardwareAssetSerialNumber = (SELECT HardwareAssetSerialNumber FROM inserted)

DECLARE @HistoryRecord TABLE (HistoryColumnName VARCHAR(256) NOT NULL, HistoryNewValue VARCHAR(256) NOT NULL)
INSERT @HistoryRecord(HistoryColumnName,HistoryNewValue) VALUES('Asset Name', @HardwareAssetTitle)
INSERT @HistoryRecord(HistoryColumnName,HistoryNewValue) VALUES('Serial Number', @HardwareAssetSerialNumber)

BEGIN

WHILE EXISTS(SELECT HistoryColumnName,HistoryNewValue FROM @HistoryRecord)

INSERT INTO HardwareAssetHistory
(HardwareAssetHistoryChangeTypeID, HardwareAssetHistoryUpdatedByID, HardwareAssetHistoryColumnName, HardwareAssetHistoryOldValue, HardwareAssetHistoryNewValue, HardwareAssetHistoryHardwareAssetID)
SELECT '1', HardwareAssetCreatedByID, HistoryColumnName, '', HistoryNewValue, HardwareAssetID
FROM HardwareAsset
WHERE HardwareAssetID = @HardwareAssetID

END
GO

任何建议或帮助都将不胜感激。

2 个答案:

答案 0 :(得分:1)

您可以在没有临时表的情况下完成此操作,并通过选择其他值来引用原始HardwareAsset表:

注意:正如@ n​​ick.mcdermaid指出的那样,当我们使用变量时,下面的行不会有效。

<击>     创建TRIGGER CreateHardwareAssetHistoryRecord         ON HardwareAsset     插入后作为     开始         DECLARE @HardwareAssetID UNIQUEIDENTIFIER,             @HardwareAssetTitle VARCHAR(256),             @HardwareAssetSerialNumber VARCHAR(256),             @HardwareAssetCreatedByID INT - 切换到什么是数据类型

    SELECT @HardwareAssetID = HardwareAssetID, @HardwareAssetTitle = HardwareAssetTitle
           , @HardwareAssetSerialNumber = HardwareAssetSerialNumber
           , @HardwareAssetCreatedByID = HardwareAssetCreatedByID FROM inserted

    INSERT INTO HardwareAssetHistory(HardwareAssetHistoryChangeTypeID
                       , HardwareAssetHistoryUpdatedByID, HardwareAssetHistoryColumnName
                       , HardwareAssetHistoryOldValue, HardwareAssetHistoryNewValue
                      , HardwareAssetHistoryHardwareAssetID)
    VALUES ('1', @HardwareAssetCreatedByID, 'Asset Name', '',  @HardwareAssetTitle
                                                     , @HardwareAssetID),
        ('1', @HardwareAssetCreatedByID, 'Serial Number', '',  @HardwareAssetSerialNumber
                                                    , @HardwareAssetID)
END
GO

<击>

更新:这也适用于多行:

CREATE TRIGGER CreateHardwareAssetHistoryRecord
    ON HardwareAsset
AFTER INSERT AS
BEGIN

    DECLARE @insertedTemp AS TABLE (HardwareAssetID UNIQUEIDENTIFIER, HardwareAssetTitle VARCHAR(256), HardwareAssetSerialNumber VARCHAR(256), HardwareAssetCreatedByID INT)

    INSERT INTO @insertedTemp(HardwareAssetID, HardwareAssetTitle, HardwareAssetSerialNumber, HardwareAssetCreatedByID) 
    SELECT HardwareAssetID, HardwareAssetTitle, HardwareAssetSerialNumber, HardwareAssetCreatedByID FROM inserted

    INSERT INTO HardwareAssetHistory(HardwareAssetHistoryChangeTypeID
                       , HardwareAssetHistoryUpdatedByID, HardwareAssetHistoryColumnName
                       , HardwareAssetHistoryOldValue, HardwareAssetHistoryNewValue
                      , HardwareAssetHistoryHardwareAssetID)    
    SELECT '1', HardwareAssetCreatedByID, 'Asset Name', '',  HardwareAssetTitle, @HardwareAssetID
    FROM    @insertedTemp

UNION    

    SELECT '1', HardwareAssetCreatedByID, 'Serial Number', '',  HardwareAssetSerialNumber, HardwareAssetID
    FROM    @insertedTemp    
END
GO

答案 1 :(得分:1)

试试这篇文章。它将帮助您了解创建AFTER INSERT触发器的每个步骤。 AFTER INSERT TRIGGERS