Поделиться через


O2SS0274. Вызов функции с возвращаемым значением курсора нельзя преобразовать в текущем контексте (ошибка)

В этой статье описывается причина, по которой Помощник по миграции SQL Server (SSMA) для Oracle не может преобразовать некоторые инструкции с курсором в качестве возвращаемого типа в любой функции.

Общие сведения

Это CURSOR механизм, с помощью которого можно назначить имя SELECT инструкции и управлять сведениями в этой инструкции SQL. Курсоры используются программистами баз данных для обработки отдельных строк, возвращаемых запросами системы базы данных.

В SSMA преобразование курсоров в операторы возврата не поддерживается. Поэтому если функция определена с курсором в качестве возвращаемого типа, 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. Вызов функции с возвращаемым значением курсора нельзя преобразовать в текущем контексте.

Возможные решения

Одним из возможных исправлений является создание и использование временной таблицы внутри функции в 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