#oracle #plsql #bulkinsert #database-cursor #table-functions
#Oracle #plsql #bulkinsert #база данных-курсор #таблица-функции
Вопрос:
Я пишу следующий код на PL / SQL, и он работает:
declare
type deliveryStat_o IS record (
warehouseName varchar2(20), shipMode char(30), thirty_days number, sixty_days number,
ninety_days number, oneTwenty_days number, veryLate number
);
type deliveryStat_t is TABLE OF deliveryStat_o;
statTable deliveryStat_t;
begin
SELECT w_warehouse_name, sm_type, 1 AS thirty_days, 1 AS sixty_days, 1 AS ninety_days,
1 AS oneTwenty_days, 1 AS veryLateDelivery
bulk collect into statTable
FROM catalog_sales, warehouse, ship_mode, date_dim
WHERE cs_ship_date_sk = d_date_sk
AND cs_warehouse_sk = w_warehouse_sk
AND cs_ship_mode_sk = sm_ship_mode_sk
GROUP BY w_warehouse_name,
sm_type ;
end;
Как я могу сделать это внутри табличной функции, которая возвращает таблицу состояния вложенной коллекции. Я понимаю, что это, вероятно, может быть достигнуто с помощью явных курсоров; однако возможно ли это сделать без использования курсора?
Комментарии:
1. Непонятно, что вы делаете. Где находится оператор insert в вашем сообщении? Что именно вы пытаетесь сделать? Пожалуйста, объясните немного больше, думая, что мы ничего не знаем.
2. Если я вас понял, у вас есть два варианта: 1. создайте тип объекта и используйте его вместо локального типа 2. Поместите тот же код, который вы показали, в пакет и сделайте функцию конвейерной.
3. Дополнительно предоставьте описание таблицы (ddl), образец тестовых данных в виде форматированного текста — никаких изображений и ожидаемого вывода этих данных.
Ответ №1:
Для контекста я начинаю с этого в качестве основы
SQL> set serverout on
SQL> declare
2 type deliveryStat_o IS record (
3 empno number, ename varchar2(20)
4 );
5 type deliveryStat_t is TABLE OF deliveryStat_o;
6
7 statTable deliveryStat_t;
8
9 begin
10
11 SELECT empno, ename
12 bulk collect into statTable
13 FROM emp;
14 dbms_output.put_line('recs='||statTable.count);
15 end;
16 /
recs=14
PL/SQL procedure successfully completed.
Чтобы преобразовать это, чтобы разрешить функцию таблицы, тогда эти типы должны быть типами SQL, следовательно
SQL> create or replace
2 type deliveryStat_o as object (
3 empno number, ename varchar2(20)
4 );
5 /
Type created.
SQL> create or replace
2 type deliveryStat_t as table of deliveryStat_o
3 /
Type created.
Теперь, когда это сделано, запрос должен возвращать таблицу объектов, поэтому
SQL> set serverout on
SQL> declare
2 statTable deliveryStat_t;
3 begin
4
5 SELECT deliveryStat_o(empno, ename)
6 bulk collect into statTable
7 FROM emp;
8 dbms_output.put_line('recs='||statTable.count);
9 end;
10 /
recs=14
PL/SQL procedure successfully completed.
который теперь можно легко преобразовать в функцию таблицы
SQL> create or replace
2 function my_func return deliveryStat_t is
3 statTable deliveryStat_t;
4 begin
5
6 SELECT deliveryStat_o(empno, ename)
7 bulk collect into statTable
8 FROM emp;
9 return statTable;
10 end;
11 /
Function created.
SQL> select * from my_func();
EMPNO ENAME
---------- --------------------
7369 SMITH
7499 ALLEN
7521 WARD
7566 JONES
7654 MARTIN
7698 BLAKE
7782 CLARK
7788 SCOTT
7839 KING
7844 TURNER
7876 ADAMS
7900 JAMES
7902 FORD
7934 MILLER
14 rows selected.
Если вы возвращаете МНОГО строк, вместо этого рассмотрите конвейерную функцию, чтобы избежать затрат памяти на сбор всех строк во вложенную таблицу