この記事では、SQL Server Migration Assistant (SSMA) for Oracle でテーブルに対してトリガーを含む ROWID
列を定義する必要がある理由について説明します。
背景
Oracle では、変更される一連の行全体ではなく、実行 FOR EACH ROW
されるトリガーを作成できます。 SQL Server では、変更された行のセット全体に対してトリガーが常に実行されます。 行レベルの Oracle トリガーが両方の :old
:new
特別な変数にアクセスする場合、SSMA では、更新の前後の特定の行の値を識別するために、両方の行セットの行を照合する方法が必要です。 このような "行ごとに" 機能をエミュレートするために、SSMA は、変更された各行を一意に識別する特別な ROWID
列を追加し、それを使用して inserted
と deleted
の行セット間のリレーションシップを確立します。
この動作は、ROWID 列の生成プロジェクト設定によって制御されます。この設定は、[ツール - プロジェクト設定] - の [一般 - 変換 - ROWID 生成] にあります。 設定が [いいえ] に設定されている場合、ROWID
列はテーブルに追加されず、SSMA はそのようなトリガーを変換できません。
例
次の Oracle トリガーは、テーブルで更新された各行に対して TRIG_TEST
実行されます。
CREATE OR REPLACE TRIGGER TSCHM.TRIG_TEST_AU
AFTER UPDATE OF DATA ON TSCHM.TRIG_TEST
FOR EACH ROW
BEGIN
IF (:new.DATA = 'ABC') THEN
INSERT INTO TSCHM.TRIG_TEST(DATA) VALUES ('-' || :old.DATA);
END IF;
END;
SSMA でこのトリガーを変換しようとすると、[ROWID 列の生成] プロジェクト設定が [いいえ] に設定されている場合、SSMA によって次のエラー メッセージが生成されます。
O2SS0239: ROWID 列にアクセスできません
考えられる対処方法
[ROWID 列の生成] プロジェクト設定を、トリガーを持つテーブルの ROWID 列を追加するように変更します。これにより、SSMA は、前の例を変換するときに、SQL Server トリガー内で次の T-SQL を生成できます。
inserted
行セットの上にカーソルを移動し、ROWID
およびDATA
列を選んで@new$0
および@new$DATA
変数を選びます。DECLARE ForEachInsertedRowTriggerCursor CURSOR LOCAL FORWARD_ONLY READ_ONLY FOR SELECT ROWID, DATA FROM inserted OPEN ForEachInsertedRowTriggerCursor FETCH ForEachInsertedRowTriggerCursor INTO @new$0, @new$DATA
挿入
ROWID
された (変数に@old$0
格納されている) に基づいて、行セットと@old$DATA
変数からdeleted
一致する行を@new$0
選びます。SELECT @old$0 = ROWID, @old$DATA = DATA FROM deleted WHERE ROWID = @new$0
変数を使用してトリガー アクションを
@old$DATA
/@new$DATA
実行します。IF (@new$DATA = 'ABC') INSERT SSMAADMIN.TRIG_TEST(DATA) VALUES (('-' + ISNULL(@old$DATA, '')))
関連する変換メッセージ
- O2SS0028: 生成された ROWID 列 (情報)
- O2SS0267: ROWID 列
- O2SS0404: ROWID 列を変換できません