Compartir a través de


O2SS0245: no se admite la conversión de CURSOR en instrucciones de retorno (error)

En este artículo se describe el motivo por el que SQL Server Migration Assistant (SSMA) para Oracle no puede convertir algunas de las instrucciones que tienen cursor como un tipo de valor devuelto en ninguna función.

Fondo

Un cursor es un mecanismo por el que puede asignar un nombre a una SELECT instrucción y manipular la información dentro de esa instrucción SQL. Los programadores de bases de datos usan cursores para procesar filas individuales devueltas por consultas del sistema de base de datos.

En SSMA, no se admite la conversión de cursores en instrucciones de retorno. Por lo tanto, si una función se define con un cursor como tipo de valor devuelto, SSMA genera un mensaje de error.

Ejemplo

Considere el ejemplo siguiente de tener un paquete PackageName, que contiene una función func_name. Esta función devuelve el cursor out_cursor definido dentro del paquete.

CREATE OR REPLACE PACKAGE PackageName AS
    TYPE Ref_cursor IS REF CURSOR RETURN emp%ROWTYPE;

    FUNCTION func_name (choice INT) RETURN Ref_cursor;
END PackageName;

La función se define como:

CREATE OR REPLACE FUNCTION func_name (choice in INT)
RETURN PackageName.ref_cursor
AS
    out_cursor PackageName.Ref_cursor;
BEGIN
    IF choice = 1 THEN
        OPEN out_cursor FOR SELECT * FROM emp WHERE comm IS NOT NULL;
    ELSIF choice = 2 THEN
        OPEN out_cursor FOR SELECT * FROM emp WHERE sal > 2500;
    ELSIF choice = 3 THEN
        OPEN out_cursor FOR SELECT * FROM emp WHERE deptno = 20;
    END IF;

    RETURN out_cursor;
END;

Cuando SSMA migra esta función, genera el siguiente error:

O2SS0245: no se admite la conversión de CURSOR en instrucciones de retorno

Posibles soluciones

Una posible corrección consiste en crear y usar una tabla temporal dentro de la función de SQL Server en lugar de usar un cursor. A continuación, la función devuelve la referencia de esta tabla temporal.

Actualice el código de SQL Server de la manera siguiente:

CREATE FUNCTION dbo.func_name
(
    @Choice int
)
RETURNS @TempEmp TABLE
(
      [EMPNO] numeric(4, 0) NOT NULL,
      [ENAME] varchar(10) NULL,
      [JOB] varchar(9) NULL,
      [MGR] numeric(4, 0) NULL,
      [HIREDATE] datetime2(0) NULL,
      [SAL] numeric](7, 2) NULL,
      [COMM] numeric](7, 2) NULL,
      [DEPTNO] numeric(2, 0) NULL,
      [ROWID] uniqueidentifier NOT NULL
)
AS
BEGIN
    IF (@Choice = 1)
    BEGIN
        INSERT INTO @TempEmp
        SELECT *
        FROM EMP where COMM is NOT NULL;
    END

    IF (@Choice = 2)
    BEGIN
        INSERT INTO @TempEmp
        SELECT *
        FROM EMP where sal > 2500;
    END

    IF (@Choice = 3)
    BEGIN
        INSERT INTO @TempEmp
        SELECT *
        FROM EMP WHERE deptno = 20;
    END

    RETURN;
END