この記事では、SQL Server Migration Assistant (SSMA) for Oracle が、ブロック レベル (つまりスタンドアロンBEGIN ... END
) のステートメントを含む PL/SQL ブロックをPRAGMA AUTONOMOUS_TRANSACTION
変換しない理由について説明します。
背景
自律トランザクションを使用すると、 親トランザクションとは無関係に変更をコミットまたはロールバックできる新しいサブトランザクションを作成できます。 PRAGMA
はコンパイラ ディレクティブを参照し、コンパイラに命令を提供するために使用されます。
Oracle では、PL/SQL ブロックを 自律トランザクションとして定義すると、そのブロック内の DML が呼び出し元のトランザクション コンテキストから分離されます。 ブロックは、メイン トランザクションと呼ばれる別のトランザクションによって開始された独立したトランザクションになります。 PL/SQL ブロックを自律トランザクションとしてマークするには、宣言セクションに次のステートメントを含めます。
PRAGMA AUTONOMOUS_TRANSACTION;
前のステートメントでは、トランザクション全体に影響を与えずに、 PRAGMA
PL/SQL ブロック内で a BEGIN
と END
ステートメントの間で自律トランザクションを実行できます。
SSMA は、ステートメント (つまりスタンドアロンBEGIN ... END
) を使用PRAGMA AUTONOMUS_TRANSACTION
して PL/SQL ブロックを変換しようとするたびに、ブロック レベルではサポートPRAGMA
されません。 これは、SSMA が対応するオブジェクトを SQL Server で見つけることができないためです。 ただし、SSMA では、自律トランザクションをルーチン レベルで変換できます (つまり、プロシージャや関数など)。
例
次の例を確認してください。
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
FOR i IN 3 .. 10 LOOP
INSERT INTO at_test (id, description)
VALUES (i, 'Description for ' || i);
END LOOP;
COMMIT;
END;
SSMA が前の PL/SQL ブロックを変換しようとすると、次のエラーが発生します。
O2SS0205: PRAGMA AUTONOMUS_TRANSACTIONを変換できません
考えられる対処方法
PL/SQL ブロックをステートメントで AUTONOMOUS_TRANSACTION
変換するには、コードをプロシージャ、関数、またはトリガーにラップする必要があります。 前の例では、自律トランザクションとしてテーブルにデータ at_test
を挿入するプロシージャを定義できます。 前の問題の解決策は次のとおりです。
CREATE OR REPLACE PROCEDURE Insert_Data
AS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
FOR i IN 3 .. 10 LOOP
INSERT INTO at_test (id, description)
VALUES (i, 'Description for ' || i);
END LOOP;
COMMIT;
END;
SSMA が自律トランザクションを変換する方法
前 の自律トランザクション ステートメントを変換するために、SSMA は拡張ストアド プロシージャ エミュレーターを使用します xp_ora2ms_exec2_ex
。 SSMA は、独立したプロシージャとして自律ブロックを作成した後、次の例に示すようにエミュレーターを xp_ora2ms_exec2_ex
使用してこのプロシージャを呼び出します。
BEGIN
DECLARE
@active_spid INT,
@login_time DATETIME
SET @active_spid = ssma_oracle.get_active_spid()
SET @login_time = ssma_oracle.get_active_login_time()
EXECUTE master.dbo.xp_ora2ms_exec2_ex
@active_spid,
@login_time,
DB_NAME(),
N'DBO',
N'INSERT_DATA$IMPL',
N'false'
END
現在の資格情報を使用して SQL Server の同じインスタンスに内部的に xp_ora2ms_exec2_ex
接続し、指定されたストアド プロシージャを実行します (INSERT_DATA$IMPL
前のサンプル)。 別の接続であるため、実行されたストアド プロシージャによって行われた変更は、呼び出し元のトランザクションとは別にコミットまたはロールバックできます。
SQL Server への新しい接続を開く必要があるため、このような変換は、ネイティブの Oracle 実装と比較して比較的低速です。 可能な限り、自律トランザクションなしでコードを 書き直します。
関連する変換メッセージ
- O2SS0292: PRAGMA AUTONOMUS_TRANSACTION変換済み
- O2SS0308: PRAGMA AUTONOMOUS_TRANSACTION無視されます