简体   繁体   中英

Pipelined function with a parameter declare with %ROWTYPE

I'm trying to declare a pipelined table function ( t ) inside a package that takes an argument declared as <tablename>%ROWTYPE . Declaring that function works and the package compiles without any error.

But I would like to use this function inside a procedure ( p1 ) like shown below.

CREATE OR REPLACE PACKAGE BODY t1
AS
   -- private

   PROCEDURE p1
   IS
      l_person   persons%ROWTYPE;
   BEGIN
      FOR l_row IN (SELECT *
                      FROM TABLE (t (l_person)))
      LOOP
         NULL;
      END LOOP;
   END;


   -- public

   FUNCTION t (p_persons_record persons%ROWTYPE)
      RETURN t_a_list
      PIPELINED
   IS
      l_a   t_a;
   BEGIN
      l_a.dummy := 'A';
      PIPE ROW (l_a);
   END;
END;

This sample code does not makes sense but it demonstrates my problem. It just doesn't compile but gives the following errors:

[Error] PLS-00382 (10: 38): PLS-00382: expression is of wrong type
[Error] PLS-00306 (10: 35): PLS-00306: wrong number or types of arguments in call to 'T'
[Error] ORA-00904 (10: 35): PL/SQL: ORA-00904: "T1"."T": invalid identifier

Can anyone explain what's wrong and how to fix those errors?

Edit:

The package spec is:

CREATE OR REPLACE PACKAGE t1
AS
   TYPE t_a IS RECORD (dummy VARCHAR2 (1));

   TYPE t_a_list IS TABLE OF t_a;

   FUNCTION t (p_persons_record persons%ROWTYPE)
      RETURN t_a_list
      PIPELINED;
END;

You cannot use a record type in SQL Scope. So a PL/SQL function with a record parameter derived by rowtype attribute cannot be used as table function in SQL. The only thing you have to rewrite is to use a SQL object on schema level instead of a PL/SQL record.

-- adapt your columns to your table as necessary
CREATE OR REPLACE TYPE g_persons AS OBJECT (
   ID int,
   C1 int
);

CREATE OR REPLACE PACKAGE t1
AS
   TYPE t_a IS RECORD (dummy VARCHAR2 (1));

   TYPE t_a_list IS TABLE OF t_a;

   FUNCTION t (p_persons_record g_persons_t)
      RETURN t_a_list
      PIPELINED;
END;
/

CREATE OR REPLACE PACKAGE BODY t1
AS
   -- private

   PROCEDURE p1
   IS
      l_person   g_persons_t;
   BEGIN

      l_person.ID := 1; -- init your record some how
      l_person.C1 := 1; -- init your record some how

      FOR l_row IN (SELECT *
                      FROM TABLE (t (l_person)))
      LOOP
         NULL;
      END LOOP;
   END;


   -- public

   FUNCTION t (p_persons_record g_persons_t)
      RETURN t_a_list
      PIPELINED
   IS
      l_a   t_a;

   BEGIN
      l_a.dummy := 'A';
      PIPE ROW (l_a);     
   END;

END;
/

I think your PACKAGE specification lacks t 's declaration. Have you checked that your PACKAGE specification is something similar to this?:

CREATE OR REPLACE PACKAGE t1 AS
   PROCEDURE p1;
   FUNCTION t (p_persons_record persons%ROWTYPE) RETURN t_a_list PIPELINED;
END;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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