The following package demonstrates the bare minimum components required to implement a PTF. All required components can be defined inside an "implementation package". Below we create an implementation package called "ptf_demo".
create or replace package ptf_demo as -- -- the implementation package must have a function called "describe" -- function describe( p_input_table_metadata in out dbms_tf.table_t ) return dbms_tf.describe_t ; -- -- this next function can either be defined here or in a standalone function -- it can have any valid name, but it must have at least one argument with a -- data type of TABLE (a new data type introduced in 18.1) -- function pass_through( p_table table ) return table pipelined row polymorphic using ptf_demo ; -- -- alternately the function can specify "PIPELINED TABLE" (for a "Table Semantics" PTF) -- instead of "PIPELINED ROW" (for a "Row Semantics" PTF) -- -- the differences will be described later in this tutorial -- /* function pass_through( p_table table ) return table PIPELINED TABLE polymorphic using ptf_demo ; */ end ptf_demo ; / create or replace package body ptf_demo as function describe( p_input_table_metadata in out dbms_tf.table_t ) return dbms_tf.describe_t as begin return null; end describe ; end ptf_demo; /
The PTF can now be invoked like this ...
select * from ptf_demo.pass_through( scott.dept ) ;
DEPTNO DNAME LOC ---------- ---------- ---------- 10 ACCOUNTING NEW YORK 20 RESEARCH DALLAS 30 SALES CHICAGO 40 OPERATIONS BOSTON
... or this
select deptno, ename from ptf_demo.pass_through( scott.emp ) where deptno = 10 ;
DEPTNO ENAME ---------- ---------- 10 KING 10 MILLER 10 CLARK
... or this
with t1 as ( select deptno, dname, ename from scott.dept join scott.emp using( deptno ) where deptno = 10 ) select t2.* from ptf_demo.pass_through( t1 ) t2 ;
DEPTNO DNAME ENAME ---------- ---------- ---------- 10 ACCOUNTING KING 10 ACCOUNTING MILLER 10 ACCOUNTING CLARK
... but not like this.
declare v_table table ; v_count pls_integer ; begin v_table := SCOTT.DEPT ; select count(*) into v_count from ptf_demo.pass_through( v_table ) ; end ; /
ORA-06550: line 3, column 11: PLS-00765: COLUMNS or TABLE is not allowed in this context ORA-06550: line 3, column 11: PL/SQL: Item ignored ORA-06550: line 8, column 3: PLS-00320: the declaration of the type of this expression is incomplete or malformed ORA-06550: line 8, column 3: PL/SQL: Statement ignored ORA-06550: line 10, column 60: PLS-00320: the declaration of the type of this expression is incomplete or malformed ORA-06550: line 10, column 60: PL/SQL: ORA-00904: "V_TABLE": invalid identifier ORA-06550: line 10, column 3: PL/SQL: SQL Statement ignored 06550. 00000 - "line %s, column %s:\n%s" *Cause: Usually a PL/SQL compilation error. *Action:
Aliasing
Multiple functions can use the same implementation package. This effectively creates function aliases.
create or replace package ptf_demo as function describe( p_table_metadata in out dbms_tf.table_t ) return dbms_tf.describe_t ; function pass_through( p_table table ) return table pipelined row polymorphic using ptf_demo ; function identity_transformation( p_table table ) return table pipelined row polymorphic using ptf_demo ; end ptf_demo ; / create or replace package body ptf_demo as function describe( p_table_metadata in out dbms_tf.table_t ) return dbms_tf.describe_t as begin return null; end describe ; end ptf_demo; /
Let's test the first PTF in the package.
select * from ptf_demo.pass_through( scott.dept ) ;
DEPTNO DNAME LOC ---------- ---------- ---------- 10 ACCOUNTING NEW YORK 20 RESEARCH DALLAS 30 SALES CHICAGO 40 OPERATIONS BOSTON
Now let's test the second PTF in the package.
select * from ptf_demo.identity_transformation( scott.dept ) ;
DEPTNO DNAME LOC ---------- ---------- ---------- 10 ACCOUNTING NEW YORK 20 RESEARCH DALLAS 30 SALES CHICAGO 40 OPERATIONS BOSTON
They both executed the same logic and returned the same results.