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