Sybaseでは、メインテーブルtest
と監査テーブル_test_a
_があります。監査テーブルは、挿入、更新、削除のトリガーによって更新されます。今問題は、古いデータ(変更なし)で更新クエリを使用すると、トリガーがまだ発生し、監査テーブルに記録されます(変更がない場合の重複を防ぐため)。
test
は
_Id | NAME | DESC
_
_test_a
_は
_updated_by | date | Id | NAME | DESC
_
これは私が持っている更新トリガーです:
_create trigger test_utrig on test for update as
insert into audit..test_a select 'update',update_by(),getdate() inserted.* from inserted
_
if (update(Id) or update(NAME) or update(DESC))
を使用しようとしましたが、変更がない場合でも更新トリガーが起動されます。変更が行われていないときにトリガーが発火しないようにする方法を教えてください。
SyBaseはわかりませんが、 ドキュメント から、1つ以上の列が更新されているかどうかを確認できるように見えます。次のように更新されているかどうかを確認するだけで十分です。
create trigger test_utrig on test
for update as
if update (id)
insert into audit..test_a (updated_by, date, Id, ,NAME, DESC)
select update_by(), getdate(), inserted.Id, inserted.NAME, inserted.DESC
from inserted
トリガーと監査テーブルの列数が一致していないようです。そのため、定数「update」を削除しました。
inserted
テーブルに情報があるかどうかだけでなく、deleted
と異なるかどうかも確認する必要があります。
Test
は
Id | NAME | DESC
Test_a
は
Event | updated_by | date | Id | NAME | DESC
このトリガーは、IDが変更されるのを防ぎ、他の列に変更があるかどうかを確認します。変更がある場合は、Test_a
テーブルに挿入します。
CREATE TRIGGER test_utrig on test for update as
IF UPDATE(Id)
BEGIN
raiserror 9000 "Can't change Id"
RETURN
END
INSERT INTO audit..test_a
SELECT 'Update',
update_by(),
getdate(),
i.*
FROM
inserted i,
deleted d
WHERE
i.Id = d.Id
AND ( i.NAME <> d.NAME
OR i.DESC <> d.DESC)
それが役に立てば幸い。
サンプルトリガーはT-SQLのようですので、(IQ、SQLAnywhereまたはAdvantageとは対照的に)ASEを使用していることを前提としているので、fwiw ...
...「古いデータを使用してクエリを更新する(変更なし)」と述べましたが、更新ではデータの変更が実行されるため(古い値と新しい値が同じであっても)、ASEでは矛盾します。
次を実行するとします。
_update tableA
set col1 = 5
where col1 = 5
_
論理的に列が更新/変更されていないと言えるかもしれません。
しかし技術的に列更新されました、つまり、Sybase ASE willの更新を実行しますカラム。つまり、_col1
_が「set」句のターゲットとして表示された場合、if update(col1)...
は常にtrueを返します。
Sybase ASEはnotを実行して古い値と新しい値を比較し、同じ値が参照されている場合は更新を「無視」します。そして、いいえ、これは愚かな/ばかげたソフトウェアの場合ではなく、むしろあなたがそれを行うように命じているソフトウェアの場合です。
この種の更新が何らかの下流のアクティビティを強制するために使用されることが何度かありました。簡単な例の1つは、表示プログラムの「最終更新」フラグの更新を強制することです(価格が変更されていなくても、「最終更新」の日付/タイムスタンプを定期的に更新する株価/為替ティッカーを考えてください。したがって、ディスプレイがフリーズ/ハングしていないことをユーザーに通知します)。
また、(T-SQL)プログラマーが注意を払っていなかったために、不要な更新でCPUサイクルを無駄にしたことも何度かありました。 [インデックスエントリを削除してから(再)挿入する必要があるため、更新された列がインデックスの一部である場合は、特に顕著になります。このため、(低速またはパフォーマンスの低い)遅延更新が発生します。]
更新を実行しない場合は、トリガーをコーディングして、列の古い/削除された値と新しい/挿入された値を比較し、適切であると考えるものを実行する必要があります。