次の方法で共有


O2SS0274: カーソル戻り値を持つ関数の呼び出しを現在のコンテキストで変換できません (エラー)

この記事では、Sql Server Migration Assistant (SSMA) for Oracle がカーソルを持つステートメントの一部を関数の戻り値の型として変換できない理由について説明します。

背景

A CURSOR は、ステートメントに名前 SELECT を割り当て、その SQL ステートメント内の情報を操作できるメカニズムです。 カーソルは、データベース システム クエリによって返される個々の行を処理するために、データベース プログラマによって使用されます。

SSMA では、return ステートメント内のカーソルの変換はサポートされていません。 したがって、関数が戻り値の型としてカーソルで定義されている場合、SSMA はエラー メッセージを生成します。

次の例を確認してください。

CREATE OR REPLACE FUNCTION F_RETURN_CUR
RETURN SYS_REFCURSOR
IS
    refCursorValue SYS_REFCURSOR;
BEGIN
    OPEN
        refCursorValue
    FOR
        SELECT * FROM dept;

    RETURN (refCursorValue);
END;
/

DECLARE
    refCursorValue SYS_REFCURSOR;
    myRecord dept%ROWTYPE;
BEGIN
    refCursorValue := F_RETURN_CUR;

    LOOP
        FETCH refCursorValue
        INTO myRecord;

        EXIT WHEN refCursorValue%NOTFOUND;

        dbms_output.put_line(refCursorValue%ROWCOUNT);
    END LOOP;
END;

Oracle で前のコードを実行すると、名前 F_RETURN_CUR を持つ関数が作成されます。 この関数はカーソルを返します refCursorValue。 SSMA がこの関数を移行すると、エラー メッセージが生成されます。

O2SS0274: カーソル戻り値を持つ関数の呼び出しは、現在のコンテキストでは変換できません

考えられる対処方法

可能な修復の 1 つは、カーソルを使用するのではなく、SQL Server の関数内に一時テーブルを作成して使用することです。 その後、この一時テーブルの参照が関数によって返されます。

次のように SQL Server コードを更新します。

CREATE FUNCTION dbo.F_RETURN_CUR()
RETURNS @TempEmp TABLE
(
   [DEPTNO] [numeric](4, 0) NOT NULL,
   [DNAME] [varchar](10) NOT NULL
)
AS
BEGIN
    INSERT INTO @TempEmp
        SELECT * FROM dept;

    RETURN;
END
GO

BEGIN
    DECLARE
        @v_refCursorValue_rowcount int,
        @refCursorValue CURSOR

    DECLARE
        @myRecord$DEPTNO float(53),
        @myRecord$DNAME varchar(20)

    DECLARE
        @TableVariable TABLE (DEPTNO INT, DNAME NVARCHAR)

    SET @refCursorValue =
        CURSOR FOR
        SELECT * FROM F_RETURN_CUR()

    OPEN @refCursorValue

    SET @v_refCursorValue_rowcount = 0

    WHILE 1 = 1
    BEGIN
        FETCH @refCursorValue
        INTO @myRecord$DEPTNO, @myRecord$DNAME

        IF @@FETCH_STATUS = 0
            SET @v_refCursorValue_rowcount = @v_refCursorValue_rowcount + 1

        IF @@FETCH_STATUS <> 0
            BREAK

        PRINT @v_refCursorValue_rowcount
    END
END