УДФ функция возвращающая более чем одну строку

 
0
 
Oracle
ava
firelex | 09.01.2004, 23:28
Доброго времени суток, all!

Проблема такая:
необходимо в БД Оракл создать функцию.
Как сделать чтобы она возвращала несколько строк, а не
одно значение (как, например, SELECT какой-ньдь)?


create or replace function xyz
(start in varchar)
return varchar
is temp varchar(30);
begin
select name into temp from values where attr= start;
return temp;
end;
/


Такая функция компилируется без ошибок, но затем на


select *
from ( xyz ('Zaire') )
;


Оракл ругается

SQL> SQL> 2 3 from ( xyz ('Zaire') )
*
ERROR in Line 2:
ORA-00907: missing right parenthesis


Если функция написана правильно, то как же тогда
получить то, что она возвращает? :bored
Comments (1)
ava
AntonSaburov | 12.01.2004, 10:50 #
Для Oracle 8i и Oracle 9i существуют так называемые "табличные функции" (конвейерные функции и функции трансформации) , которые умеют возвращать набор данных, который можно рассматривать, как реляционную таблицу в предложении FROM.

Для их создания надо:
1. В предложении RETURN определить тип возвращаемых функцией данных как коллекцию (вложенную таблицу или VARRAY)

2. Поместить вызовы функции в операторы TABLE и CAST

Как пример (вытащил из книжки smile ):

1. Создадим табличный тип

CREATE TYPE pet_t IS OBJECT (
NAME VARCHAR2 (60),
breed VARCHAR2 (100),
dob DATE);
/

CREATE TYPE pet_nt IS TABLE OF pet_t;


2. Создадим функцию, которая принимает в качестве аргументов два объекта типа pet_t - mon_in (мать) и dad_in (отец) и возвращает таблицу о составе его "семьи"

CREATE OR REPLACE FUNCTION pet_family (dad_in IN pet_t, mom_in IN pet_t)
RETURN pet_nt
IS
l_count PLS_INTEGER;
retval pet_nt := pet_nt();

PROCEDURE extend_assign (pet_in IN pet_t) IS
BEGIN
retval.EXTEND;
retval (retval.LAST) := pet_in;
END;

BEGIN
extend_assign(dad_in);
extend_assign (mon_in);

IF mom_in.breed = 'RABBIT' THEN l_count := 12;
ELSIF mon_in.breed = 'DOF' THEN l_count := 4;
ELSIF mon_in.breed = 'KANGAROO' THEN l_count := 1;
END IF;

FOR indx IN 1 .. l_count
LOOP
extend_assign(pet_t ('BABY' || indx, mom_in.breed, SYSDATE));
END LOOP;

RETURN retval;
END;


3. Теперь эту функцию можно вызвать так:

SELECT * FROM TABLE ( CAST (
pet_family(
pet_t('Hoppy', 'RABBIT', SYSDATE),
pet_t('Hippy', 'RABBIT', SYSDATE)
) AS pet_nt
));
Please register or login to write.
Firm of day
Вы также можете добавить свою фирму в каталог IT-фирм, и публиковать статьи, новости, вакансии и другую информацию от имени фирмы.
Подробнее
Contributors
advanced
Submit