私は2つのテーブルを持っています。1 つのテーブルには、単にカウンターを保持するために使用される 1 つのフィールドがあり、もう 1 つのテーブルには多数の検索フィールドがあり、これらのフィールドの 1 つに他のテーブルのカウンター値が含まれている必要があります。
トリガーを作成しようとしています
- 2 番目のテーブルで更新が発生すると、最初のテーブルの値を 1 増やします
- 最初のテーブルから増分された値は、2 番目のテーブルのフィールドを設定するために使用されます
- 1 & 2 は、更新が 2 番目のテーブルで発生し、フィールド、つまりステータスが特定の値に等しい場合にのみ発生します。
- 複数のレコードに対して 1、2、および 3 を処理します。
1) なんとかこのトリガーを書きましたが、a) ひどく遅いようです。b) それをかなりよく説明している記事を見つけましたが、例が示すように、これは 1 つのレコードのみです。複数のレコードが更新された場合は解決策を提供しますが、私の問題は、各レコードの最初のテーブルの値をインクリメントしてから、個々のレコードをそれぞれの新しい値で更新する方法ですか?
なぜ遅いのか(まあ、SQL Server管理コンソールで)何か考えはありますか?
私が見つけた記事はhttp://benreichelt.net/blog/2005/12/13/make-a-trigger-fire-on-column-change/にあります。
この記事をもとに書いたトリガーは以下の通りです。
CREATE TRIGGER [dbo].[trig_DataTable] ON [dbo].[DataTable]
FOR UPDATE
AS
IF UPDATE(Status)
BEGIN
SET NOCOUNT ON;
DECLARE @newStatus NVARCHAR(50)
DECLARE @oldStatus NVARCHAR(50)
DECLARE @maxRefNo INT
DECLARE @id BIGINT
SET @maxRefNo = (SELECT MAX(RefNo) FROM CounterTable) + 1
UPDATE CounterTable SET RefNo = @maxRefNo
SET @newStatus = (SELECT Status FROM Inserted)
SET @oldStatus = (SELECT Status FROM Deleted)
IF (@newStatus != @oldStatus) AND (@newStatus = 'Approved')
BEGIN
SET @Id = (SELECT Id FROM Inserted)
UPDATE DataTable
SET UniqueRef = @maxRefNo
WHERE Id = @Id
END
END
上記に関して、もう 1 つ質問があります。上記のトリガーは単一のレコードに対してのみ機能するため、where 部分が必要ですか? これを必要とするのは意味がないようです。
私が必要とするのは上記と同じ動作であるため、それほど重要ではありませんが、INSERTED/DELETED テーブルに含まれる複数のレコードに対してそれを処理する必要があります。
次の使用可能な番号を取得して CounterTable を更新する関数を作成し、記事で説明されているように、同様の SQL からこの関数を呼び出すことはできますか?
INSERT INTO PriceHistory(ItemId, OldPrice, NewPrice, UniqueRef)
SELECT I.ItemId, D.Price, I.Price, dbo.GetNextRefNo()
FROM INSERTED I INNER JOIN DELETED D ON I.ItemId = D.ItemId
WHERE I.Price != D.Price
正直に言うと... すぐに試してみますが、これを達成する方法についてアイデアをお持ちの方がいらっしゃいましたら、お知らせください... 素晴らしいことです! ありがとう。
上記が理にかなっていることを願っています。
乾杯。
T.