2017-03-06 16 views
0

私は最初のSQL Serverトリガを作成しており、別のテーブルに挿入した後に「履歴」テーブルにINSERTすることを検討しています。私は、コードの大部分を書いていると思いますが、構文が完成したように見えません。現在の書式では、「HistoryColumnName」および「HistoryNewValue」が無効であることが示されています。変数テーブル@HistoryRecordにJOINしようとしましたが、独立しているので意味がありません。以下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 

任意の提案やヘルプをいただければ幸いです。

注:

+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

最初に学ぶべきことは、最初のトリガーライターの間違いです。つまり、トリガーはバッチごとに1回呼び出され、1回に1回は呼び出されません。言い換えれば、 'SET @ HardwareAsetID =(SELECT HardwareAssetID FROMが挿入されました)'という文は、この場合エラーをスローします。 –

+1

テーブル 'HardwareAsset'に' HistoryColumnName'?私はそうは思わない。それは間違いの直接の原因ですが、理解しておくべき他の概念があるという大きな問題の症状に過ぎません。 –

答えて

1

あなたは別の値を選ぶことによって、あなたの一時テーブルと参照元HardwareAsset台なしにこれを達成することができます@ nick.mcdermaidで指摘したように、以下の複数の行があるときは動作しません、我々が使用しているとして変数。

INSERT AS がされたものと DECLARE @HardwareAssetID UNIQUEIDENTIFIER、 @HardwareAssetTitle VARCHAR(256)、 @HardwareAssetSerialNumber VARCHAR(256)、 @HardwareAssetCreatedByID INT --changeを開始した後HardwareAsset ON TRIGGER CreateHardwareAssetHistoryRecord をCREATE THIS

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 'が複数のレコードを持つ場合、これは期待どおりに機能しません。すべての変数を使用せずに、単純に挿入/選択を行うと機能します。新しいソリューションは複数の行で動作します。@ Nick.McDermaidの良い点は、 –

+1

です。 – TheVillageIdiot

+1

'@ insertedTemp'がここでも必要であるかどうかわかりませんが、論理がわかりません。 –

1

は、この記事をお試しください。それは、AFTER INSERTトリガーを作成する各ステップを理解するのに役立ちます。 AFTER INSERT TRIGGERS

関連する問題