Oracle конвейерная функция
Я пытаюсь создать функцию, которая возвращает объект, который можно использовать в предложении FROM. Согласно исследованию документации оракула, я обнаружил, что мне нужна функция PIPELINED.
У меня есть этот код:
CREATE TYPE type_struct AS OBJECT
(
i NUMBER
);
CREATE TYPE tp_struct AS TABLE OF type_struct;
CREATE OR REPLACE FUNCTION gen_nums (na NUMBER, nb NUMBER)
RETURN tp_struct PIPELINED
IS
rec type_struct;
counter NUMBER;
BEGIN
counter := na;
WHILE (counter <= nb)
LOOP
SELECT counter
INTO rec
FROM dual;
counter := counter + 1;
PIPE ROW (rec);
END LOOP;
RETURN;
END gen_nums;
/
Предполагаемый результат - таблица с записями от 'na' до 'nb', включительно.
Однако я получаю эту ошибку при компиляции функции:
ORA 00932 ожидаемые несоответствующие типы данных udt получил номер
2 ответа
ORA 00932 inconsistent datatypes expected udt got number
Вы получаете это, потому что ваш код назначает скаляр для типа вывода. Вам нужно привести переменную в соответствие с целью назначения. Так:
SELECT type_struct(counter)
INTO rec
FROM dual;
Вам не обязательно нужна конвейерная функция. Мы можем использовать table()
с любой функцией, которая возвращает коллекцию.
Вот намного более простая реализация, которая требует только одного UDT.
CREATE TYPE tp_numbers AS TABLE OF number;
/
CREATE OR REPLACE FUNCTION gen_nums (na NUMBER, nb NUMBER)
RETURN tp_numbers
IS
return_value tp_numbers ;
BEGIN
SELECT (na + level) - 1
bulk collect INTO return_value
FROM dual
connect by level <= nb;
RETURN return_value ;
END gen_nums;
/
CREATE OR REPLACE FUNCTION gen_nums (na NUMBER, nb NUMBER)
RETURN sys.DBMS_DEBUG_VC2COLL PIPELINED --sys.DBMS_DEBUG_VC2COLL an oracle provided collection type.
IS
counter NUMBER;
BEGIN
counter := na;
WHILE (counter <= nb)
LOOP
PIPE ROW (counter);
counter := counter + 1;
END LOOP;
RETURN;
END gen_nums;