1

Gotcha alert re where 句を尊重するように on update トリガーを調整するのに助けが必要です。

SQL Server 2008。メイン テーブルには、たとえば 12345 行あります。私の意図は、更新時に、更新が完了したときに更新中のレコードのみを履歴テーブルにコピーしたいということです。where 句で更新すると、where 句によって制限された影響を受けるレコードだけでなく、トリガーがテーブル全体を転送していることがわかります。

Production の History テーブルは Development と同じデータ構造を持たないため、Select から Prod 構造をコピーして貼り付けました。SQL Server の第一人者ではありませんが、Dev トリガーを見逃していたことに気付かずfrom insert、Select の実際のテーブル名を Prod のトリガーに残しました。

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE trigger [dbo].[myTable_LogUpdate] 
ON [dbo].[myTable]
FOR UPDATE
AS
    INSERT INTO myTable_Hist ([ID], [FLD_1], ..., [FLD_N], [HIST_DT])
        SELECT 
            [ID], [FLD_1], ..., [FLD_N], GETDATE() AS HIST_DT
        FROM
            [dbo].[myTable] -- <<< this should be FROM inserted
GO

EXEC sp_settriggerorder @triggername=N'[dbo].[myTable_LogUpdate]', @order=N'Last', @stmttype=N'UPDATE'
GO

たとえば、5 つのレコードを更新するために where 句を使用して更新を実行すると、次のようになります。

USE [myDb]

update myTable 
set FLD_7 = 2 
where FLD_1 = 10 and FLD_2 = 20

メッセージで私は2つの応答を受け取ります:

(12345 rows affected)
(5 rows affected)

また、履歴テーブルの前後で count(*) を実行すると、12345 行すべてがmyTable_LogUpdateテーブルに挿入されたことが示されます (これは非常に膨大であり、クリーンアップが切実に必要です)。

更新:ドライブのディスク容量が不足していたため、元の Prod トリガーを削除する必要がありました。元の投稿のトリガー コードは Dev からのものだったので、Prod で実行していた実際の問題のあるトリガー コードではなく、正しいコードが表示されていました。OPはバグではなかったので、SOの第一人者が私が抱えていた問題に答える方法はありませんでした。

OPを更新して、問題のコードが何であるかを反映し、修正が必要な場所を表記しました。履歴テーブルを再作成し、トリガーを修正したところ、from inserted適切に機能するようになりました。

ショーンのコメントが私をこの啓示に導いてくれたことに感謝します。

4

0 に答える 0