Compartir a través de


O2SS0331: No se puede convertir la instrucción FETCH (error)

En este artículo se describe por qué SQL Server Migration Assistant (SSMA) para Oracle proporciona un error al convertir la FETCH ... INTO instrucción en un procedimiento en el que se devuelve como SYS_REFCURSOR parámetro.

Fondo

En Oracle, SYS_REFCURSOR se usa para pasar cursores de y a un procedimiento almacenado.

Cada vez que SSMA encuentra una variable para SYS_REFCURSOR como un tipo de valor devuelto del procedimiento y usa la misma variable con FETCH ... INTO la instrucción , genera un mensaje de error.

Ejemplo

En el ejemplo siguiente, se declara una variable como SYS_REFCURSOR, que se usa como un tipo de valor devuelto de un procedimiento.

CREATE OR REPLACE PROCEDURE p_close_refcursor
(
    emp_refcur OUT SYS_REFCURSOR
)
IS
    departmentno dept.deptno%TYPE;
BEGIN
    OPEN
        emp_refcur
    FOR
        SELECT deptno
        FROM dept;

    LOOP
        FETCH emp_refcur
        INTO departmentno;

        EXIT WHEN emp_refcur%NOTFOUND;

        DBMS_OUTPUT.PUT_LINE(departmentno);
    END LOOP;

    CLOSE emp_refcur;
END;

Al intentar convertir el código anterior en SSMA, genera el siguiente mensaje de error:

O2SS0330: No se puede convertir la instrucción FETCH

Posibles soluciones

Hay dos posibles soluciones para corregir este error.

Uso de la variable de cursor local

El primer método consiste en crear y usar un cursor local para realizar todas las operaciones y, a continuación, pasar su valor al cursor devuelto antes de cerrarlo. Declare una nueva variable de SYS_REFCURSOR tipo, que es local para este procedimiento. Modifique el código para usar este cursor local para realizar la operación necesaria, incluida FETCH ... INTO la instrucción . Antes de cerrar el cursor local, pase el valor de este cursor local al cursor definido en la sección de parámetros del procedimiento (emp_refcur en nuestro ejemplo).

La solución para el error anterior se muestra en el código siguiente:

CREATE OR REPLACE PROCEDURE p_close_refcursor
(
    emp_refcur OUT SYS_REFCURSOR
)
AS
    test_cursor SYS_REFCURSOR;
    departmentno dept.deptno%TYPE;
BEGIN
    OPEN
        test_cursor
    FOR
        SELECT deptno
        FROM dept;

    LOOP
        FETCH test_cursor
        INTO departmentno;

        EXIT WHEN test_cursor%NOTFOUND;

        DBMS_OUTPUT.PUT_LINE(departmentno);
    END LOOP;

    emp_refcur := test_cursor;

    CLOSE test_cursor;
END;

Devolver conjunto de resultados

Otra manera de resolver este error es usar el mismo enfoque que SQL Server, es decir, devolver el conjunto de resultados directamente de ejecutar procedimientos almacenados. Este enfoque se explica en detalles en el artículo para O2SS0157 mensaje de conversión.