1

「ライブ」テーブルと履歴テーブルの2つのテーブルがあるとします。ライブテーブルは次のようになります。

CREATE TABLE dbo.LiveTable (
    LiveTableId INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
    SomeVarChar VARCHAR(20) NOT NULL DEFAULT '',
    SomeForeignId INT NULL,
    OtherForeingId INT NULL,
    ChangeBy VARCHAR(128) NOT NULL,
    ChangeTime DATETIME NOT NULL DEFAULT GETDATE()
)

履歴テーブルは、独自の主キーと他のIsDelete場所で使用される列があることを除いて、同じように見えます。ユーザーがの行を更新するときに、LiveTableその行の以前の値を履歴テーブルに記録したいと思います。UPDATEもちろん、これはトリガーを使えば十分に簡単です。しかし、更新の一部が履歴テーブルの挿入を起動していないと判断したところです。これは、nullを許可するフィールドが原因であると考えています。私のトリガーは次のようになります。

CREATE TRIGGER dbo.trgLiveTableUpdate ON dbo.LiveTable FOR UPDATE
AS
INSERT INTO dbo.LiveTableHistory (
    LiveTableId,
    SomeVarChar,
    SomeForeignId,
    OtherForeignId,
    ChangeBy,
    ChangeTime
)
SELECT 
    d.LiveTableId,
    d.SomeVarChar,
    d.SomeForeignId,
    d.OtherForeignId,
    d.ChangeBy,
    d.ChangeTime
FROM DELETED d
JOIN INSERTED i ON d.LiveTableId = i.LiveTableId
WHERE d.SomeVarChar <> i.SomeVarChar
OR d.SomeForeignId <> i.SomeForeignId   //<--- I don't think this works
OR d.OtherForeignId <> i.OtherForeignId //<--- this either

WHERE変更がtoである状況、SomeForeignIdまたはOtherForeignIdこれらの列の両方でnullが許可されている状況で、私の条件がヒットしていない可能性はありますか?もしそうなら、それらの列の不平等をチェックするときにヌルを考慮に入れる条件をどのように書くのですか?

4

3 に答える 3

3

また、記録するキーを提供する EXCEPTions を見つけることもできます。

select 
    d.LiveTableId,
    d.SomeVarChar,
    d.SomeForeignId,
    d.OtherForeignId,
    d.ChangeBy,
    d.ChangeTime
from DELETED d
join
(
select LiveTableId, SomeVarChar, SomeForeignId, OtherForeignId from INSERTED
EXCEPT 
select LiveTableId, SomeVarChar, SomeForeignId, OtherForeignId from DELETED
) e on e.LiveTableId = d.LiveTableId
于 2012-10-02T19:04:51.510 に答える
2
WHERE d.SomeVarChar <> i.SomeVarChar
OR ISNULL(d.SomeForeignId,-987654) <> ISNULL(i.SomeForeignId,-987654)
OR ISNULL(d.OtherForeignId,-987654) <> ISNULL(i.OtherForeignId,-987654)

*-987654 は、ID 列の未使用の数字に過ぎないことに注意してください。ID 列にリンクする場合は、-1 で十分です。

于 2012-10-02T18:53:49.603 に答える
1

質問ではありませんが、変更がない場合は更新を停止することを検討してください。

変更がない場合は、更新を防ぐことができます。

update live table  
set SomeVarChar  = 'a' 
where SomeVarChar is null or SomeVarChar  != 'a'

一度に1つのレコードだけの場合は、要因ではありません。
ただし、値の99%がすでに'a'である場合のグローバル更新SomeVarChar='a'は、多くの非更新です。

はい、トリガーを修正します。

パフォーマンスの問題がある場合に考慮すべき点。

于 2012-10-02T20:02:16.007 に答える