Как вернуть набор ЧИСЕЛ из функции в PLSQL, а затем использовать его в ЦИКЛЕ FOR?

#oracle #plsql

#Oracle #plsql

Вопрос:

Я хотел иметь функцию в PLSQL, которая возвращала бы набор чисел, а затем иметь цикл for, который выполнял бы итерации по этому набору данных и что-то с ним делал.

Есть предложения? Должна ли функция быть конвейерной, чтобы ее можно было использовать в цикле for? Нужно ли мне создавать новый тип, даже если я просто возвращаю числа?

Спасибо!

  CREATE OR REPLACE PACKAGE BODY someBody AS

      FUNCTION getListOfNumbers RETURN someList IS -- what type do I return ??
      BEGIN
        RETURN SELECT SID FROM V$SESSION;  -- Not sure what do here ??
      END;

      PROCEDURE soSomeStuff IS
      BEGIN
        FOR rec IN(getListOfNumbers)  -- how do I select from the function?
        LOOP
          dbms_output.put_line(rec);
        END LOOP;
      END;
  END;
  

Ответ №1:

Вам нужно будет объявить тип коллекции:

 SQL> CREATE OR REPLACE PACKAGE my_package AS
  2  
  3     TYPE someList IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
  4  
  5     FUNCTION getListOfNumbers RETURN someList;
  6     PROCEDURE soSomeStuff;
  7  
  8  END my_package;
  9  /

Package created
  

Затем вы бы использовали определенный тип следующим образом:

 SQL> CREATE OR REPLACE PACKAGE BODY my_package AS
  2  
  3     FUNCTION getListOfNumbers RETURN someList IS
  4        l_list someList;
  5     BEGIN
  6        SELECT SID BULK COLLECT INTO l_list FROM V$SESSION;
  7        RETURN l_list;
  8     END;
  9  
 10     PROCEDURE soSomeStuff IS
 11        l_list someList;
 12     BEGIN
 13        l_list := getListOfNumbers;
 14        FOR i IN 1..l_list.count LOOP
 15           dbms_output.put_line(l_list(i));
 16        END LOOP;
 17     END;
 18  
 19  END my_package;
 20  /

Package body created

SQL> exec my_package.soSomeStuff;

284
285
287
288
[...]
PL/SQL procedure successfully completed
  

Комментарии:

1. Здорово, я об этом не подумал … В итоге я использовал конвейерную функцию (преимущество в том, что я мог поместить ее непосредственно в forloop ie. для записи (выберите * из таблицы (getListOfNUmbers))