自分自身を再帰的に呼び出すトリガーの代わりに取得するのに苦労しています。
テーブルに行が挿入されると、その時点で評価された特定の条件に基づいてトリガーが配置され、行データを変更して挿入するという考え方です。また、これらの条件が満たされた場合、2番目の行が同じテーブルに挿入され、トリガーが起動して、以前のように新しく挿入された値を評価し、データを変更して2番目の行を挿入します。 TRIGGER_NESTLEVEL()
が特定の値(常に3未満)に達した。
私が思うに、2番目の挿入時にトリガーを再度実行するようには見えないようです。
これが私の問題を説明するために私が書いたサンプルコードです。
_--delete Tester1
--go
--drop table Tester1
alter database Playground
set recursive_triggers on
go
create table Tester1(ID int identity, Val int, String varchar(255))
go
Create trigger [tr_Tester1]
on Tester1
instead of insert
as
Begin
if(Select TRIGGER_NESTLEVEL()) >= 3
Return
--Insert the initial row (modify text based on criterion)
insert into Tester1
select
inserted.Val,
case
when inserted.Val%2 = 0
then 'modified ' + inserted.String --Insert modified text
else
inserted.String --Insert the original text
end
from inserted
--Insert a second row if the criterion was satisfied
insert into Tester1
select
inserted.Val * 2, --Insert a new value that should satisfy the condition
'some more text ' + CAST(TRIGGER_NESTLEVEL() as varchar(5))
FROM inserted
where
inserted.Val%2 = 0
End
insert into Tester1(Val, String)
values(2,'some text')
select * from Tester1
_
私が見ている結果:
期待していた結果:
私はSELECT DATABASEPROPERTYEX('Playground', 'IsRecursiveTriggersEnabled')
と_select * from sys.configurations where name like 'nested triggers'
_を確認しましたが、 [〜#〜] msdn [〜#〜] に従って両方が有効になっています:
「これらのアクションは他のトリガーを開始することができます。DMLトリガーとDDLトリガーは最大32レベルまでネストできます。ネストされたトリガーのサーバー設定オプションを通じてAFTERトリガーをネストできるかどうかを制御できます。INSTEADOFトリガー(DMLトリガーのみがINSTEAD OFトリガー)は、この設定に関係なくネストできます。」
また、私の例では、私のロジックが常に再帰をもたらすことに気付いています(少なくとも、理論的には)。ただし、これは問題を説明するためだけのものです。実際のトリガーでは、これは必ずしもそうではありません。
誰かが私が欠けているものを指摘したり、私のアプローチが間違っている場合は教えてください。
INSTEAD OF
トリガーは、操作の実行時にそれ自体を直接呼び出すことはありません。
トリガーが行を挿入するのに、値が偶数の場合に限っては、最初のステートメントに非常に近く見え、再帰させたくないと考えてください。
テーブルで定義されたINSTEAD OFトリガーが、通常は再度INSTEAD OFトリガーを起動するテーブルに対してステートメントを実行する場合、トリガーは再帰的に呼び出されません。代わりに、ステートメントはテーブルにINSTEAD OFトリガーがないかのように処理され、一連の制約操作とAFTERトリガー実行を開始します。
これは、INSTEAD OF
を再帰の一部にすることができないという意味ではありません。トリガーが別のテーブルに変更を加える場合、それらはそれらのトリガーを呼び出します。トリガーは前後に跳ね返り、そのように再帰を作成できます。
元の挿入を制御するINSTEAD OF
と追加の行を追加するAFTER
トリガーを組み合わせることで、意図した動作を得ることができると思います。