次の方法で共有


O2SS0205: PRAGMA AUTONOMOUS_TRANSACTIONを変換できません (エラー)

この記事では、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 BEGINEND ステートメントの間で自律トランザクションを実行できます。

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無視されます