简体   繁体   English

PL/SQL 将本地集合传递到流水线函数中

[英]PL/SQL Passing a local collection into a pipelined function

I need to pass a locally defined table type to a function which is a pipelined function returning another locally defined table type.我需要将本地定义的表类型传递给函数,该函数是返回另一个本地定义的表类型的流水线函数。

Here is sample data:这是示例数据:

create table my_tab
(i NUMBER,
 n VARCHAR2(30));

 insert into my_tab values (1, 'Peter');
 insert into my_tab values (2, 'Dakshesh');
 insert into my_tab values (1, 'Maggie');
 insert into my_tab values (3, 'Madhu');
 commit;

My code is:我的代码是:

CREATE OR REPLACE PACKAGE my_pkg IS
    TYPE t_col IS RECORD(
    i NUMBER,
    n VARCHAR2(30));
    TYPE t_nested_table IS TABLE OF t_col;
    TYPE t_number IS TABLE OF NUMBER;
    FUNCTION iterate_table RETURN t_number PIPELINED;
    FUNCTION return_table(in_t_num t_number) RETURN t_nested_table PIPELINED;
     g_number t_number ;
     g_nested_number t_nested_table ;
  END my_pkg;
  /

Body:身体:

 CREATE OR REPLACE PACKAGE BODY my_pkg IS
    FUNCTION iterate_table RETURN t_number PIPELINED IS
    BEGIN
      IF ( (g_number IS NOT NULL) AND (g_number.EXISTS (1)))
      THEN
         FOR i IN 1 .. g_number.COUNT
         LOOP
            IF g_number (i) IS NOT NULL
            THEN
               PIPE ROW (g_number (i));
            END IF;
         END LOOP;
      END IF;
      RETURN;
   EXCEPTION
      WHEN OTHERS
      THEN
         RAISE;
   END iterate_table;

   FUNCTION return_table(in_t_num t_number) RETURN t_nested_table PIPELINED IS
      l_row t_nested_table ;
      CURSOR cur_test IS
          select mt.i, mt.n 
          from my_tab mt, TABLE(iterate_table ) tab
          where mt.i = tab.column_value;
     BEGIN
         OPEN cur_test;
         FETCH cur_test BULK COLLECT into l_row;
         CLOSE cur_test;
         FOR i IN 1..l_row.COUNT
         LOOP
             PIPE ROW(l_row(i));
         END LOOP;
         RETURN;
     END return_table;
 END my_pkg;
 /

Now this code compiles successfully, when I try to invoke it like a pipelined function, it gives error-现在这段代码编译成功,当我尝试像流水线函数一样调用它时,它给出了错误-

select * from table(my_pkg.return_table(my_pkg.t_number(1)));

Error- ORA-00902: invalid datatype 00902. 00000 - "invalid datatype" *Cause:
*Action: Error at Line: 14 Column: 41
错误- ORA-00902: invalid datatype 00902. 00000 - "invalid datatype" *Cause:
*Action: Error at Line: 14 Column: 41
ORA-00902: invalid datatype 00902. 00000 - "invalid datatype" *Cause:
*Action: Error at Line: 14 Column: 41

The two pre-requisites for this code are -此代码的两个先决条件是 -

  1. the collections should be all locally defined.集合应该都是本地定义的。

  2. the function should be pipelined.该函数应该是流水线的。

Help!!帮助!!

I am not getting any error with table and its a single table so no foreign key constraints hold.我没有收到任何表及其单个表的错误,因此没有外键约束。

It is not possible in oracle 11. I don't know why oracle throws "invalid data type".在oracle 11中是不可能的。我不知道oracle为什么会抛出“无效数据类型”。 If you put this query into anonymous block you will receive PLS-00642: Local Collection Types Not Allowed in SQL Statement如果将此查询放入匿名块,您将收到PLS-00642: Local Collection Types Not Allowed in SQL Statement

If you don't want or you cannot create sql level collection.如果您不想或无法创建 sql 级别的集合。 The solution is use predefined type.解决方案是使用预定义类型。 Good source of predefined collection is Oracle Data Cartridge .预定义集合的良好来源是Oracle Data Cartridge Replace all t_number with ODCINumberList .t_number替换所有ODCINumberList

predefined collections 预定义集合

In Oracle 10 and 11, it is not possible to use collections in the SQL scope that have been defined in a PL/SQL scope.在 Oracle 10 和 11 中,无法在 SQL 范围内使用已在 PL/SQL 范围中定义的集合。 In Oracle 12 , what you are trying should work. 在 Oracle 12 中,您正在尝试的应该有效。

If you want to do this then declare your types in the SQL scope (not in the package).如果您想这样做,请在 SQL 范围内(不在包中)声明您的类型。

CREATE OR REPLACE TYPE t_col IS OBJECT(
  i NUMBER,
  n VARCHAR2(30)
);
/

CREATE OR REPLACE TYPE t_nested_table IS TABLE OF t_col;
/

CREATE OR REPLACE TYPE t_number IS TABLE OF NUMBER;
/

CREATE OR REPLACE PACKAGE my_pkg IS
  FUNCTION iterate_table RETURN t_number PIPELINED;
  FUNCTION return_table(in_t_num t_number) RETURN t_nested_table PIPELINED;
  g_number t_number ;
  g_nested_number t_nested_table ;
END my_pkg;
/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM