Imagine that I have an object definition A
CREATE TYPE A
AS OBJECT (
col1 NUMBER
);
and a collection tbl_a
CREATE TYPE tbl_a AS TABLE OF a;
Now, assume that I need to have two pipelined table functions (F1 and F2) that return TBL_A collections. These functions will share the same logic, so I want one function to call the other. Assuming that F1 is defined as
CREATE FUNCTION f1( arg IN NUMBER )
RETURN tbl_a
PIPELINED
IS
BEGIN
FOR x IN 1..100
LOOP
PIPE ROW( new a( x ) );
END LOOP;
RETURN;
END;
then I can define F2 as
CREATE FUNCTION f2( arg IN NUMBER )
RETURN tbl_a
PIPELINED
IS
local_a a;
BEGIN
FOR x IN (SELECT * FROM TABLE( f1( arg ) ) )
LOOP
local_a := new a( x.col1 );
PIPE ROW( local_a );
END LOOP;
RETURN;
END;
Is there a way to accomplish the same thing but without having to go through the effort of creating a new instance of my object in F2? Essentially, if the object definition changes, I would like to be able to just change F1 without worrying about F2.
One option would be to create a helper function that returns a non-pipelined collection of objects and have cookie-cutter logic in F1 & F2 to pipeline the collection, i.e.
CREATE FUNCTION helper_func( arg IN NUMBER )
RETURN tbl_a
IS
...
CREATE FUNCTION f1( arg IN NUMBER )
RETURN tbl_a
PIPELINED
IS
local_table_a tbl_a := helper_func( arg );
BEGIN
FOR x IN local_table_a.FIRST .. local_table_a.LAST
LOOP
PIPE ROW( local_table_a(x) );
END LOOP;
RETURN;
END;
This, however, requires that we read the entire collection into memory at once, which would use a bit more RAM than we're comfortable using.
Any other options?
Thanks,
Justin