Most excellent!
Mark J. Bobak, August 12, 2004 - 1:18 pm UTC
Thanks for the correction!
Also, I'll think more about what you said with regard to SQL types.
Thanks again!
(Sometimes I just can't see the forest for the trees....;-))
Clarification please
A reader, December 11, 2006 - 6:25 am UTC
Hi Tom,
Continuing from the example above.
From my understanding, since the return type of the function is declared as a new SQL type, you don't really need to have the function defined as PIPELINED. Is there any (dis)advantage of then defining the function as PIPELINED? Does it make the function more efficient?
Thanks
December 11, 2006 - 8:08 am UTC
if the function is not pipelined - then
plsql will be used to fill a collection in it's entirety. If that means "one billion rows", that will be one billion rows in memory. The client will wait until the last row is produced before getting the first row.
if the function is pipelined - then
plsql will be used to "pipe" back as many rows as the client has requested (array fetch size), then plsql will "suspend" and client will get control - processing the array fetch size number of rows. When and if the client asks for the next batch of rows - plsql will start again and continue working. At no time do we need to have memory to hold one billion rows and the client gets the first row as fast as it can (and if you don't ask for the last row, we never have to actually produce it)
Perfect..
A reader, December 11, 2006 - 8:44 am UTC
Hi Tom,
Thanks for the quick answer.
Would you recommend using pipelined functions when creating Reports as well?
Thanks
December 11, 2006 - 9:42 am UTC
I'd use "regular queries"
pipelined functions should be rather few and far between
o utilities like dbms_xplan
o ETL functions (extract/transform/load) maybe
very special purpose. but yes, I would use a pipelined function over and above a function that returns a collection - but I would use NEITHER if I could avoid them and just use SQL
Excellent say about the function Pipelined...
Gowtham Sen, December 25, 2006 - 5:42 am UTC
Hi Tom,
Its very good explanation about fcunctionality of a function to be pipelined or not.
While I am working with pipelined function I am facing with an error since 2 days.
The error I am getting is
"PLS-00306: wrong number or types of arguments in call to 'DATE_DIM_DATA_TABLE'"
The steps I followed in creating the pipelined function are as follows.
SQL> drop function GEN_DATE_DIM;
Function dropped
SQL> drop type Date_Dim_Data_Table;
Type dropped
SQL> drop type Date_Dim_Data;
Type dropped
Create or replace type Date_Dim_Data is object
2 ( Dt DATE NULL,
3 Day_Num INTEGER NULL,
4 Day_Nm VARCHAR2(30) NULL,
5 Week_Num INTEGER NULL,
6 Mnth_Num INTEGER NULL,
7 Mnth_Yr_Num INTEGER NULL,
8 Mnth_Nm VARCHAR2(20) NULL,
9 Qtr_Yr_Num INTEGER NULL,
10 Yr_Num INTEGER NULL,
11 Fiscal_Yr_Num INTEGER NULL
12 );
SQL> /
Type created
SQL> create or replace type Date_Dim_Data_Table
2 is table of Date_Dim_Data;
SQL> /
Type created
SQL> create or replace function Gen_Date_Dim
2 (
3 startDate IN VARCHAR2, -- start date
4 numYears IN NUMBER -- number of years
5 )
6 return Date_Dim_Data_Table
7 pipelined
8 is
9
10 V_Dt Date_Dim.Dt%type:=NULL;
11 V_Day_Num Date_Dim.Day_Num%type := NULL;
12 V_Day_Nm Date_Dim.Day_Nm%type:= NULL;
13 V_Week_Num Date_Dim.Week_Num%type:= NULL;
14 V_Mnth_Num Date_Dim.Mnth_Num%type:= NULL;
15 V_Mnth_Yr_Num Date_Dim.Mnth_Yr_Num%type:= NULL;
16 V_Mnth_Nm Date_Dim.Mnth_Nm%type:= NULL;
17 V_Qtr_Yr_Num Date_Dim.Qtr_Yr_Num%type:= NULL;
18 V_Yr_Num Date_Dim.Yr_Num%type:= NULL;
19 V_Fiscal_Yr_Num Date_Dim.Fiscal_Yr_Num%type:= NULL;
20
21 V_Current_Dt Date_Dim.Dt%type:=NULL;
22
23 begin
24
25 loop
26
27 --Date Conversion.
28 V_Current_Dt := to_date(Startdate,'DD/MM/YYYY');
29 V_Current_Dt := V_Current_Dt - 1 ;
30
31 for V_Num_years in 1 .. NumYears
32 loop
33
34 -- The Next date is genearated using Start date.
35 V_Dt := V_Current_Dt + 1;
36
37 --Day Num :
38 V_Day_Num := wb_day_of_week(V_Dt);
39
40 --Day Name : It give the day name.
41 V_Day_Nm := wb_day_name(V_Dt);
42
43 --Week Num :
44 V_Week_Num :=wb_week_of_month(V_Dt);
45
46 --Month Number
47 V_Mnth_Num := wb_cal_month_of_year(V_Dt);
48
49 --Month Year Number ??????
50 V_Mnth_Yr_Num := NULL;
51
52 --Month Name
53 V_Mnth_Nm := wb_cal_month_name(V_Dt);
54
55 --Quarter Year Number
56 V_Qtr_Yr_Num := wb_cal_qtr(V_Dt);
57
58 --Yearr Number
59 V_Yr_Num := wb_cal_year(V_Dt);
60
61 --Fiscal Year Number ?????
62 V_Fiscal_Yr_Num := NULL;
63
64 V_Current_Dt := V_Dt;
65
66 pipe row (Date_Dim_Data_Table(V_Dt,V_Day_Num,V_Day_Nm,V_Week_Num,V_Mnth_Num,NULL,V_Mnth_Nm,V_Qtr_Yr_Num,V_Yr_Num,NULL));
67
68
69 end loop;
70
71
72 end loop;
73
74 end Gen_Date_Dim;
75 /
Warning: Function created with compilation errors
SQL> show errors
Errors for FUNCTION OWB_WRHS.GEN_DATE_DIM:
LINE/COL ERROR
-------- ------------------------------------------------------------------------------
66/17 PLS-00306: wrong number or types of arguments in call to 'DATE_DIM_DATA_TABLE'
66/17 PLS-00306: wrong number or types of arguments in call to 'DATE_DIM_DATA_TABLE'
66/17 PLS-00306: wrong number or types of arguments in call to 'DATE_DIM_DATA_TABLE'
66/17 PLS-00306: wrong number or types of arguments in call to 'DATE_DIM_DATA_TABLE'
66/17 PLS-00306: wrong number or types of arguments in call to 'DATE_DIM_DATA_TABLE'
66/17 PLS-00306: wrong number or types of arguments in call to 'DATE_DIM_DATA_TABLE'
66/17 PLS-00306: wrong number or types of arguments in call to 'DATE_DIM_DATA_TABLE'
66/17 PLS-00306: wrong number or types of arguments in call to 'DATE_DIM_DATA_TABLE'
66/7 PL/SQL: Statement ignored
I verified the types of data, I am passing to the object and the number of objects i am passing.
Please help me. Please explain why is it so.
Thank you,
Regards
Gowtham Sen
December 25, 2006 - 7:42 am UTC
you have a date_dim_data element you are returning, NOT the _table type
You used the wrong type
Thank you Tom.
Gowtham Sen, December 25, 2006 - 6:07 am UTC
Hi Tom,
I got that. My mistake was here.
pipe row (Date_Dim_Data_Table(V_Dt,V_Day_Num,V_Day_Nm,V_Week_Num,V_Mnth_Num,NULL,V_Mnth_Nm,V_Qtr_Yr_Num,V_Yr_Num,NULL));
Instead of giving the object name, I have given the table object name.
Now I corrected as
pipe row (Date_Dim_Data(V_Dt,V_Day_Num,V_Day_Nm,V_Week_Num,V_Mnth_Num,NULL,V_Mnth_Nm,V_Qtr_Yr_Num,V_Yr_Num,NULL));
Now the fucntion created successfully.
Thank you,
Regards,
Gowtham Sen.
Can we define an object using table.column%type syntax
Naresh, September 28, 2007 - 2:54 pm UTC
Hello Tom,
Can we define object type using table_name.column%type?
Meaning I tried something like:
create or replace type myObject as object
(
m1 table1.column1%type
)
/
It gives as error - so I need to know if there i sany way to base it on table column data type. I want to use the object in a pipelined function ultimately.
Thanks,
Naresh
October 03, 2007 - 12:55 pm UTC
no, that is plsql syntax only.
Table function in Package
Rajeshwaran, Jeyabal, September 28, 2011 - 10:36 am UTC
Tom:
I am invoking a Table function defined in a package and getting this error.
Is that Table function defined in package are not suppored in SQL?
rajesh@ORA10GR2> create or replace package pkg_test
2 as
3 type emp_rec is record
4 (p_empno number,p_ename varchar2(20));
5 type emp_rec_ntt is table of emp_rec;
6 function emp_fnc return emp_rec_ntt;
7 end;
8 /
Package created.
Elapsed: 00:00:00.03
rajesh@ORA10GR2>
rajesh@ORA10GR2> create or replace package body pkg_test as
2 function emp_fnc
3 return emp_rec_ntt
4 as
5 l_result pkg_test.emp_rec_ntt := pkg_test.emp_rec_ntt();
6 begin
7 for x in (select * from emp)
8 loop
9 l_result.extend;
10 l_result(l_result.count).p_empno := x.empno;
11 l_result(l_result.count).p_ename := x.ename;
12 end loop;
13 return l_result;
14 end;
15
16 end;
17 /
Package body created.
Elapsed: 00:00:00.03
rajesh@ORA10GR2>
rajesh@ORA10GR2> select * from table (pkg_test.emp_fnc);
select * from table (pkg_test.emp_fnc)
*
ERROR at line 1:
ORA-00902: invalid datatype
Elapsed: 00:00:00.03
rajesh@ORA10GR2>
rajesh@ORA10GR2> select * from table (cast(pkg_test.emp_fnc as pkg_test.emp_rec_ntt));
select * from table (cast(pkg_test.emp_fnc as pkg_test.emp_rec_ntt))
*
ERROR at line 1:
ORA-00902: invalid datatype
September 28, 2011 - 12:42 pm UTC
You cannot reference a plsql type in SQL, SQL is "below" plsql - plsql can see sql types - sql does not see plsql types.
You would create EMP_REC as an object, and EMP_REC_NTT as a table of that - at the SQL level. Move those out of the package and use CREATE TYPE in SQL.
also, use a pipelined function
ops$tkyte%ORA11GR2> create type emp_rec as object
2 ( empno number, ename varchar2(20) )
3 /
Type created.
ops$tkyte%ORA11GR2> create type emp_rec_ntt as table of emp_rec;
2 /
Type created.
ops$tkyte%ORA11GR2>
ops$tkyte%ORA11GR2> create or replace package pkg_test
2 as
3 function emp_fnc return emp_rec_ntt pipelined;
4 end;
5 /
Package created.
ops$tkyte%ORA11GR2>
ops$tkyte%ORA11GR2> create or replace package body pkg_test
2 as
3
4 function emp_fnc return emp_rec_ntt
5 PIPELINED
6 as
7 begin
8 for x in ( select emp_rec(empno, ename) data from scott.emp)
9 loop
10 pipe row( x.data );
11 end loop;
12 return;
13 end;
14
15 end;
16 /
Package body created.
ops$tkyte%ORA11GR2>
ops$tkyte%ORA11GR2> select * from table( pkg_test.emp_fnc );
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.
helped alot
praneeth kumar, October 28, 2011 - 7:09 am UTC
hi tom , i got issue in creating reports , so i got good solution here.
simply super. thanks thanks thank u very much