Как вернуть несколько строк из хранимой процедуры? (Oracle PL / SQL)

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

ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
46
0
217 370
5

Ответы 5

Я думаю, вы хотите вернуть РЕФКУРСОРА:

create function test_cursor 
            return sys_refcursor
            is
                    c_result sys_refcursor;
            begin
                    open c_result for
                    select * from dual;
                    return c_result;
            end;

Обновлять: если вам нужно вызвать это из SQL, используйте табличную функцию, например, предложенную @Tony Andrews.

я хотел бы использовать что-то подобное, так как я не знаю свои поля заранее. Но select * from test_cursor дает "попытку доступа к строкам элемента, тип которого неизвестен ..."

johny why 14.05.2016 19:11

Вот как создать функцию, которая возвращает набор результатов, который можно запрашивать, как если бы это была таблица:

SQL> create type emp_obj is object (empno number, ename varchar2(10));
  2  /

Type created.

SQL> create type emp_tab is table of emp_obj;
  2  /

Type created.

SQL> create or replace function all_emps return emp_tab
  2  is
  3     l_emp_tab emp_tab := emp_tab();
  4     n integer := 0;
  5  begin
  6     for r in (select empno, ename from emp)
  7     loop
  8        l_emp_tab.extend;
  9        n := n + 1;
 10       l_emp_tab(n) := emp_obj(r.empno, r.ename);
 11     end loop;
 12     return l_emp_tab;
 13  end;
 14  /

Function created.

SQL> select * from table (all_emps);

     EMPNO ENAME
---------- ----------
      7369 SMITH
      7499 ALLEN
      7521 WARD
      7566 JONES
      7654 MARTIN
      7698 BLAKE
      7782 CLARK
      7788 SCOTT
      7839 KING
      7844 TURNER
      7902 FORD
      7934 MILLER

Думаю, для этого требуется 10 г, но это самое элегантное решение. (Ненавижу ссылочные курсоры).

Osama Al-Maadeed 17.11.2008 22:07

Это не изящное решение, потому что вам нужно создавать типы для всех таблиц с разными столбцами.

zygimantus 16.09.2016 16:03

Если вы хотите использовать его в простом SQL, я бы позволил процедуре хранилища заполнять таблицу или временную таблицу результирующими строками (или использовать подход @Tony Andrews). Если вы хотите использовать решение @ Thilo, вам нужно зациклить курсор с помощью PL / SQL. Вот пример: (Я использовал процедуру вместо функции, как @Thilo)

create or replace procedure myprocedure(retval in out sys_refcursor) is
begin
  open retval for
    select TABLE_NAME from user_tables;
end myprocedure;

 declare 
   myrefcur sys_refcursor;
   tablename user_tables.TABLE_NAME%type;
 begin
   myprocedure(myrefcur);
   loop
     fetch myrefcur into tablename;
     exit when myrefcur%notfound;
     dbms_output.put_line(tablename);
   end loop;
   close myrefcur;
 end;

Точка с запятой после notfound была добавлена ​​в соответствии с комментарием (опубликованным как ответ) Даниэль.

Jonas Heidelberg 16.03.2012 04:25

Вы можете использовать конвейерные функции Oracle

Basically, when you would like a PLSQL (or java or c) routine to be the «source» of data -- instead of a table -- you would use a pipelined function.

Простой пример - создание случайных данных
Как вы могли создать N уникальных случайных чисел в зависимости от входного аргумента?

create type array
as table of number;


create function  gen_numbers(n in number default null)
return array
PIPELINED
as
begin
  for i in 1 .. nvl(n,999999999)
  loop
     pipe row(i);
 end loop;
 return;
end;

Допустим, нам для чего-то понадобилось три ряда. Теперь мы можем сделать это одним из двух способов:

select * from TABLE(gen_numbers(3));

COLUMN_VALUE


       1
       2
       3

или же

select * from TABLE(gen_numbers)
 where rownum <= 3;

COLUMN_VALUE


       1
       2
       3

конвейерные функции1конвейерные функции2

+1 Думаю, в большинстве случаев это подходящее решение. В отличие от решения Тони Эндрюса, оно не создает все строки заранее и требует меньше памяти.

miracle173 16.06.2014 12:37

Я увеличил количество голосов с 1 до 2, и голос за него отображается в моем браузере

miracle173 16.06.2014 14:00

create procedure <procedure_name>(p_cur out sys_refcursor) as begin open p_cur for select * from <table_name> end;

Другие вопросы по теме