2017-03-06 163 views
0

我正在創建我的第一個SQL Server觸發器,並且在插入另一個表後查找INSERT到「歷史記錄」表中。我認爲我編寫了大部分代碼,但似乎無法完成語法。當前格式指出「HistoryColumnName」和「HistoryNewValue」無效。我已經嘗試了JOIN到變量表@HistoryRecord,但它沒有真正意義,因爲它們是獨立的。下面SQL Server:爲審計/歷史記錄創建觸發器表

代碼:

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 

任何建議或幫助,將不勝感激。

注意:因爲我們使用的是由@ nick.mcdermaid如指出,下面就不會當有多個行

+1

您可能希望使用時態表。 https://www.google.com.au/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0ahUKEwjKt5OGg8PSAhUJzbwKHQf5B_8QFggZMAA&url=https%3A%2F%2Fmsdn.microsoft.com%2Fen-us%2Flibrary%2Fdn935015。 aspx&usg = AFQjCNG2VZa8v6Y_rCW-rWB_2VTUW1-Idw&sig2 = fouMv9WhcDjahToxkDiWoQ&bvm = bv.148747831,d.dGc&cad = rja如果您剛剛開始學習SQL,請允許我向您保證避免使用觸發器。雖然你可以學習構建一個重要的概念,但在實踐中,它們通常不是一個好主意。 –

+4

首先要學習的是由_every_首次觸發作者所犯的錯誤。那就是每個批次觸發一次,而不是每行一次。換句話說,'inserted'表可以有多行,這意味着在這種情況下'SET @HardwareAssetID =(SELECT HardwareAssetID FROM FROM inserted)'語句會引發錯誤 –

+1

表'HardwareAsset'是否有一個名爲' HistoryColumnName'?我猜不會。這是你錯誤的直接原因,但這只是一個更大問題的症狀,你需要了解其他一些概念 –

回答

1

您可以通過選擇其他值做到這一點沒有你的臨時表且參考原來HardwareAsset表變量。

CREATE TRIGGER CreateHardwareAssetHistoryRecord ON HardwareAsset INSERT AS BEGIN DECLARE @HardwareAssetID UNIQUEIDENTIFIER, @HardwareAssetTitle VARCHAR(256), @HardwareAssetSerialNumber VARCHAR(256), @HardwareAssetCreatedByID INT --change什麼是後這

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 

01數據類型

UPDATE:這將多行以及工作:

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 
+2

當'inserted'具有多條記錄時,這不會按預期運行。如果您不需要任何變量,只需執行插入/選擇 –

+1

@ Nick.McDermaid好點匹配,新解決方案可以處理多行數據,它將起作用。 – TheVillageIdiot

+1

我不知道'@ insertedTemp'在這裏甚至是必要的,但是我不太明白邏輯 –