BEFOREトリガーをトリガーに置き換えることができる場合もありAFTERますが、挿入が行われる前に明らかに値を提供する必要があるため、これはあなたの状況には当てはまらないようです。そのため、@marc_s がコメントで示唆しているように、最も近い機能はINSTEAD OFトリガー機能のようです。
BEFOREただし、これら 2 つのトリガー タイプの名前が示すように、トリガーとトリガーには根本的な違いがあることに注意してくださいINSTEAD OF。どちらの場合も、トリガーを呼び出したステートメントによって決定されるアクションが発生していないときにトリガーが実行されますが、トリガーの場合INSTEAD OF、アクションはまったく発生しないはずです。実行する必要がある実際のアクションは、トリガー自体によって実行する必要があります。BEFOREこれは、明示的にロールバックしない限り、ステートメントが常に実行されるトリガー機能とは大きく異なります。
しかし、実際に取り組むべき問題がもう 1 つあります。Oracle スクリプトが明らかにしているように、変換する必要があるトリガーは、SQL Server でサポートされていない別の機能を使用していますFOR EACH ROW。SQL Server にも行ごとのトリガーはなく、ステートメントごとのトリガーのみです。つまり、挿入されたデータは単一の行ではなく、行セットであることに常に留意する必要があります。これにより複雑さが増しますが、説明する必要があるもののリストはおそらくこれで終わりです。
したがって、実際に解決すべきことは次の 2 つです。
機能を置き換えBEFOREます。
機能を置き換えFOR EACH ROWます。
これらを解決するための私の試みは以下のとおりです。
CREATE TRIGGER sub_trg
ON sub1
INSTEAD OF INSERT
AS
BEGIN
DECLARE @new_super TABLE (
super_id int
);
INSERT INTO super (subtype_discriminator)
OUTPUT INSERTED.super_id INTO @new_super (super_id)
SELECT 'SUB1' FROM INSERTED;
INSERT INTO sub (super_id)
SELECT super_id FROM @new_super;
END;
上記の仕組みは次のとおりです。
に挿入されるのと同じ数の行sub1が最初に に追加されsuperます。生成super_idされた値は、一時ストレージ ( と呼ばれるテーブル変数@new_super) に格納されます。
新しく挿入されたsuper_idが に挿入されsub1ます。
それほど難しいことはありませんが、上記はsub1、質問で指定した列以外に列がない場合にのみ機能します。他の列がある場合、上記のトリガーはもう少し複雑にする必要があります。
super_id問題は、挿入されたすべての行に個別に新しい s を割り当てることです。マッピングを実装する 1 つの方法は、次のようになります。
CREATE TRIGGER sub_trg
ON sub1
INSTEAD OF INSERT
AS
BEGIN
DECLARE @new_super TABLE (
rownum int IDENTITY (1, 1),
super_id int
);
INSERT INTO super (subtype_discriminator)
OUTPUT INSERTED.super_id INTO @new_super (super_id)
SELECT 'SUB1' FROM INSERTED;
WITH enumerated AS (
SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS rownum
FROM inserted
)
INSERT INTO sub1 (super_id, other columns)
SELECT n.super_id, i.other columns
FROM enumerated AS i
INNER JOIN @new_super AS n
ON i.rownum = n.rownum;
END;
ご覧のとおり、IDENTIY(1,1)列が に追加される@new_userため、一時的に挿入されたsuper_id値が 1 から追加で列挙されます。新しいsuper_idと新しいデータ行の間のマッピングを提供するために、ROW_NUMBER関数を使用してINSERTED行も列挙します。その結果、INSERTEDセット内のすべての行を 1 つの行にリンクできるようになりsuper_id、完全なデータ行を補完して に挿入できるようになりましたsub1。
新しいsuper_idが挿入される順序は、割り当てられる順序と一致しない場合があることに注意してください。私はそれを問題にしないと考えました。生成されたすべての新しいsuper行は、ID を除いて同一です。したがって、ここで必要なのは、新しい行super_idごとに新しいものを 1 つ取得することだけです。sub1
ただし、挿入のロジックsuperがより複雑で、何らかの理由で、どの新しい行super_idに対してどの新しい行が生成されたかを正確に覚えておく必要があるsub場合は、このスタック オーバーフローの質問で説明されているマッピング方法を検討することをお勧めします。