This doesn't seem to work
Robin Trei, June 01, 2005 - 10:21 am UTC
When I follow your suggestion: I get the following error:
ORA-00904: "TST_REGULARIZE": invalid identifier
I have created a small test program that shows my original attempt (that worked), the one that compiled and failed, and your suggestion. I'm not sure it will make the 1000 word limit:
drop table test_reg0;
drop table test_base;
create table test_reg0 ( sample_time number(11), element_id number (11) , var108 number(38,7));
create table test_base as select * from test_reg0;
create view test_view as select * from test_base;
insert into test_base (sample_time, element_id, var108) values ( 1117631002, 1000001, 2049.81006);
insert into test_base (sample_time, element_id, var108) values ( 1117631302, 1000001, 1608);
insert into test_base (sample_time, element_id, var108) values (1117631601, 1000001, 2063.1001);
insert into test_base (sample_time, element_id, var108) values ( 1117631903, 1000001, 2579.08008);
insert into test_base (sample_time, element_id, var108) values ( 1117632201, 1000001, 2410.82007);
insert into test_base (sample_time, element_id, var108) values ( 1117632501, 1000001, 2808);
/
create or replace
TYPE testData_t as object (
sample_time NUMBER(11) ,
element_id NUMBER(11) ,
var108 NUMBER(38,7)
);
/
Create or replace package
testdata_pkg as
TYPE TestDataRecSet_t IS TABLE OF TestData_t;
FUNCTION tst_regularize (c1 IN sys_refcursor) return TestDataRecSet_t pipelined;
procedure tst_nh_regularize (statsView VARCHAR2, startUTC NUMBER, endUTC NUMBER);
end testdata_pkg;
/
create or replace package body
testdata_pkg is
cursor stats_cursor is select * from test_base;
--=====================================================
--ROUTINE: REGULARIZE
--
-- This is the heart of the regularization process
-- Given a cursor, it will return regularized rows of data
--=================================================
FUNCTION tst_regularize (c1 IN sys_refcursor)
RETURN TestDataRecSet_t pipelined
--PARALLEL_ENABLE(PARTITION c1 BY ANY)
IS
in_rec stats_cursor%ROWTYPE;
out_rec testData_t := testData_t(
NULL, NULL, NULL );
begin
LOOP
FETCH c1 INTO in_rec;
EXIT WHEN c1%NOTFOUND;
out_rec.sample_time := in_rec.sample_time;
out_rec.element_id := in_rec.element_id;
out_rec.var108 := in_rec.var108;
pipe row(out_rec);
end loop;
RETURN;
end tst_regularize;
procedure tst_nh_regularize (statsView VARCHAR2, startUTC NUMBER, endUTC NUMBER)
IS
-- call this as tst_nh_regularize('test_base', 1117631002, 1117632501)
start_date NUMBER;
end_date NUMBER;
num_loops NUMBER;
sqlCommand VARCHAR2(1000);
statsViewCursor sys_refcursor;
BEGIN
-- if you uncomment the lines marked '*1' you get a program that works, but relies on a view being regenerated
-- If you uncomment the lines marked '*2' you get a program that runs, but produces an ora-22905 exception
-- If you uncomment the lines marked '*3*' you get the program change you suggested, which does not recognize the table function
-- it returns: ORA-00904: "TST_REGULARIZE": invalid identifier
--*1* sqlCommand := 'create or replace view test_view as select * from ' || statsView;
--*2* open statsViewCursor for 'select sample_time, element_Id, var108 from ' || statsView ;
--*3* sqlCommand := 'select sample_time, element_id, var108 from ' || statsView;
--*3* execute immediate '
insert /* append */ into test_reg0
select sample_time, element_id,
VAR108
from table(tst_regularize(
--*3* cursor(' || sqlCommand || ')
--*1* cursor(select * from test_view)
--*2* statsViewCursor
))
--*3* '
;
--*2* close statsViewCursor;
END tst_nh_regularize;
end testdata_pkg;
/
June 01, 2005 - 11:23 am UTC
so, what does it fail with (please, for a test case -- remove everything NOT RELEVANT -- like all of the commented lines, hacked code -- short, sweet, to the point)
and use dbms_output to print out your generated sql, you might well find the bug in the generated SQL rapidly that way.
but I can say:
from table(tst_regularize(
^^^^^ missing PACKAGE NAME
(an example for me should be "easy" to work with -- 1, 2, 3 isn't "easy" and I don't have the table stats_cursor so even when I go to 3, the code doesn't compile)
you are quite correct, this does work!
Robin Trei, June 01, 2005 - 11:44 am UTC
You are quite correct, this does work. The problem was that I forgot the package name and it mattered when I went to dynamic sql.
(I had just done so many versions of trying to solve this problem that I was completely misinterpreting what the error message was saying.)
Thank you very much for your time, I really appreciate the help. I do apologize that my demo script was not helpful, I can understand how truly busy you are.
June 01, 2005 - 1:49 pm UTC
I think that tomorrow I'll blog about "how to ask other people questions" (no slam on you -- really, not at all).
I do get lots of them, as do the forums in general. There are some simple things that would make it lots easier for people to answer if they had it up front :)
(ran out of time today, no blog for me -- off to the richmond Oracle user group, be on the road for 6 hours driving instead of typing)
Same things on my mind
Holger Bär, June 03, 2005 - 7:49 am UTC
<quote> I think that tomorrow I'll blog about "how to ask other people questions" (no
slam on you -- really, not at all).</quote>
You must be kidding, right? I was thinking about starting a blog myself and that would have been the very first item.
So I'll be enjoying your blog instead.
Id pleae
Srinivasan. A, September 27, 2005 - 1:28 am UTC
I have many doubts in oracle & vb. pls tell me which Id to send my question?
Thanks and regards
Srinivasan. A
September 27, 2005 - 11:00 am UTC
Dynamic pipelined functions?
J L, October 01, 2005 - 12:57 am UTC
Hi Tom,
Thanks,
I would like your help to create a function that would select certain columns of a given query (for the example it will be a table), based on columns defined in another table.
But I would like to use pipelined functions,
Here are the tables ..
create table x
( col1 varchar2(10),
col2 varchar2(10),
col3 varchar2(10),
col4 varchar2(10),
col5 varchar2(10),
col6 varchar2(10)
) ;
create table v
( v_name varchar2(20),
v_order integer ,
v_col_name varchar2(20)
) ;
insert into x values ( 'EMP','2321','PETER1','SMITH1','11-SEP-05','OFF01' ) ;
insert into x values ( 'EMP','2322','PETER2','SMITH2','12-SEP-05','OFF02' ) ;
insert into x values ( 'EMP','2323','PETER3','SMITH3','13-SEP-05','OFF03' ) ;
insert into x values ( 'EMP','2324','PETER4','SMITH4','14-SEP-05','OFF01' ) ;
insert into x values ( 'EMP','2325','PETER5','SMITH5','15-SEP-05','OFF04' ) ;
insert into x values ( 'EMP','2326','PETER6','SMITH6','16-SEP-05','OFF05' ) ;
insert into x values ( 'EMP','2327','PETER7','SMITH7','17-SEP-05','OFF06' ) ;
insert into v values ( 'VIEW01',1,'COL1' );
insert into v values ( 'VIEW01',2,'COL2' );
insert into v values ( 'VIEW01',3,'COL3' );
insert into v values ( 'VIEW01',4,'COL4' );
insert into v values ( 'VIEW02',1,'COL1' );
insert into v values ( 'VIEW02',2,'COL5' );
insert into v values ( 'VIEW02',3,'COL6' );
commit ;
the desired output should be:
select * from table ( MyFunction ( 'VIEW01' ) ) ;
COL1 COL2 COL3 COL4
---- ---- ------ ------
EMP 2321 PETER1 SMITH1
EMP 2322 PETER2 SMITH2
EMP 2323 PETER3 SMITH3
EMP 2324 PETER4 SMITH4
EMP 2325 PETER5 SMITH5
EMP 2326 PETER6 SMITH6
EMP 2327 PETER7 SMITH7
and in case the parameter is changed, should give other columns ...
select * from table ( MyFunction ( 'VIEW02' ) ) ;
COL1 COL5 COL6
---- --------- ------
EMP 11-SEP-05 OFF01
EMP 12-SEP-05 OFF02
EMP 13-SEP-05 OFF03
EMP 14-SEP-05 OFF01
EMP 15-SEP-05 OFF04
EMP 16-SEP-05 OFF05
EMP 17-SEP-05 OFF06
Actually my question is if a pipelined function can be created and defined to return a generic ref cursor ?
Your suggestions are greately appreciated,
October 01, 2005 - 9:02 pm UTC
pipelined functions do not RETURN ref cursors, they return collections!
How to return a collection with unnown number of columns
Maya, November 29, 2007 - 6:04 pm UTC
I think what author meant (and what I am trying to figure out) is how to write a pipeline function which takes a sys_refcursor as a parameter (meaning you do not know how many columns are in the cursor select list) and returns a collection (of what type?) each record of which is a fetched cursor record. In this case you can query this table function as you would query from any view.
Thanks.
November 29, 2007 - 7:20 pm UTC
you cannot do that in 10g and before - not until 11g would anything remotely similar to this be possible (and I haven't even thought about trying it there because I question "why")
you need to turn the ref cursor into a dbms_sql cursor, you can do that in 11g.