Ref cursors pls help
hi,
what is ref cursor, what is its advantage over normal cursor.
How we can pass a cursor as an argument to a procedure??
How we return a cursor from a procedure??
RTFM [url http://oraclesvca2.oracle.com/docs/cd/B10501_01/appdev.920/a96624/06_ora.htm#1510]Using Cursor Variables
Similar Messages
-
Hi,
I am new to Ref Cursor concepts and I am trying a small block but its throwing error. Pls help me.
PACKAGE SPEC:
CREATE OR REPLACE PACKAGE PKG_JOBINFO AS
PROCEDURE JOBINFO ( v_job_id IN number, p_cursor OUT PKG_JOBINFO.RESULT_REF_CURSOR);
TYPE RESULT_REF_CURSOR IS REF CURSOR;
END PKG_JOBINFO;
PACKAGE BODY:
CREATE OR REPLACE package body PKG_JOBINFO
AS
PROCEDURE JOBINFO ( v_job_id IN number,
p_cursor OUT PKG_JOBINFO.RESULT_REF_CURSOR)
AS
BEGIN
OPEN p_cursor FOR
SELECT JOB_ID,
JOB_NAME,
TABLE_NAME
FROM JOB_INFO
WHERE JOB_ID=V_JOB_ID;
EXCEPTION
WHEN OTHERS THEN
raise;
END;
END;
While compiling the package i am not getting any errors. I am getting errors only while executing
SQL> exec PKG_JOBINFO.JOBINFO ('23');
BEGIN PKG_JOBINFO.JOBINFO ('23'); END;
ERROR at line 1:
ORA-06550: line 1, column 7:
PLS-00306: wrong number or types of arguments in call to 'JOBINFO'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
Please help me to resolve this error.
Thanks.user497267 wrote:
Thanks its working. So if we are using ref cursor we have to execute like this only.To add...
The actual issue you were experiencing was not because you were using ref cursors specifically, but because you had an OUT parameter in your procedure.
When you have an OUT parameter, you need to ensure that you pass in a variable to that parameter of the procedure in order that the procedure can populate it. In your case you were only passing in the first parameter, but you weren't passing in a variable to capture the OUTput.
What Alex showed was that by declaring a variable of the same datatype (ref cursor in your case) and passing that in as the second parameter, that variable was populated with the ref cursor information from inside the procedure. Once that variable was populated, after the procedure call, the data from that ref cursor can be obtained (using SQL*Plus' print command in Alex's example). -
Need Help: Using Ref Cursor in ProC to call a function within a Package
I'm calling a function within a package that is returning a REF CURSOR.
As per the Oracle Pro*C Programmer's Guide, I did the following:
1) declared my cursor with a: EXEC SQL BEGIN DECLARE SECTION and declared the cursor as: SQL_CURSOR my_cursor;
2) I allocated the cursor as: EXEC SQL ALLOCATE :my_cursor;
3) Via a EXEC SQL.....END-EXEC begin block
I called the package function and assign the return value to my cursor
e.g. my_cursor := package.function(:host1, :host2);
Now, the only difference between my code and the example given in the Pro*C Programmer's Guide is that the example calls a PROCEDURE within a package that passes back the REF CURSOR as an OUT host variable.
Whereas, since I am calling a function, the function ASSIGNS the return REF CURSOR in the return value.
If I say my_cursor := package.function(:host1, :host2); I get a message stating, "PLS-00201: identifier MY_CURSOR" must be declared"
If I say :my_cursor := package.function(:host1, :host2); I get a message stating, "ORA-01480: trailing null missing from STR bind value"
I just want to call a package function and assign the return value to a REF CURSOR variable. There must be a way of doing this. I can do this easily in standard PL/SQL. How can this be done in Pro*C ???
Thanks for any help.Folks, I figured it out. For those who may face this problem in the future you may want to take note for future reference.
Oracle does not allow you to assign the return value of a REF CURSOR from a FUNCTION ( not Procedure - - there is a difference) directly to a host variable. This is the case even if that host variable is declared a CURSOR variable.
The trick is as follows: Declare the REF CURSOR within the PL/SQL BEGIN Block, using the TYPE statement, that will contain the call to the package function. On the call, you then assign the return REF CURSOR value that the function is returning to your REF CURSOR variable declared in the DECLARE section of the EXEC SQL .... END-EXEC PL/SQL Block.
THEN, assign the REF CURSOR variable that was populated from the function call to your HOST cursor varaible. Then fetch this HOST Cursor variable into your Host record structure variable. Then you can deference individual fields as need be within your C or C++ code.
I hope this will help someone facing a deadline crunch. Happy computing ! -
Ref cursor help in Reports/pl sql
Hello , i am new to this , please help!
From oracle forms, we have a table and one of the columns from that table returns rows and the result are like ( select name, messaging_id, listing_id from dynamic_message group_query) ..I am trying to join this table with other tables based on a group type, based on if it returns 'D' or 'S' to other groups in report.
I am getting the following error when I uncomment the open cursor statemnt
PLS-00455: cursor 'TEMP_GRP_REC_REFCUR' cannot be used in dynamic
SQL OPEN statement
This is what i have so faar:
create or replace PACKAGE grp IS
TYPE grp_rec IS RECORD
(listing_id varchar2(16 ),
messaging_id varchar2(16 ),
name varchar2(256 ) ,
group_number Number);
TYPE grp_rec_refcur is REF CURSOR RETURN grp_rec;
function grprefc(P_group_number NUMBER, P_group_type CHAR) return grp_rec_refcur;
END;
CREATE OR REPLACE PACKAGE BODY grp IS
function grprefc(p_group_number Number )
return grp_rec_refcur
IS
temp_grp_rec_refcur grp.grp_rec_refcur;
v_stmt_str VARCHAR2(2000) := NULL;
v_cov_name listing.name%TYPE := NULL;
v_cov_mid listing.messaging_id%TYPE := NULL;
v_cov_lid listing.listing_id%TYPE := NULL;
v_grpnum message_group.group_number%TYPE := NULL;
BEGIN
v_stmt_str:='SELECT dmgq.resolved_query
INTO v_stmt_str
FROM dynamic_message_group_query dmgq
WHERE dmgq.group_number = p_group_number';
OPEN temp_grp_rec_refcur FOR v_stmt_str;
LOOP
FETCH temp_grp_rec_refcur INTO v_cov_lid , v_cov_mid ,v_cov_name, v_grpnum ;
EXIT WHEN temp_grp_rec_refcur %NOTFOUND;
END Loop;
RETURN temp_grp_rec_refcur;
END;
END;
show errors;
if there are any examples done by someone in reoprts or if you can help me solve the above, i would higghly appreciate it .
Thanks and Good Day!Maybe something like my second example "Dynamic Table in the Second Query with Oracle Reports"
- ref cursor or "simple" query Q1, which has a column "group_type", linked to a ref cursor query Q2.
Ref cursor query Q2 - pseudo code for function:
CREATE OR REPLACE PACKAGE BODY grp IS
FUNCTION A_join_B_or_A_join_C_join_D
(p_group_type CHAR(1), p_group_number NUMBER)
RETURN dynamic_refcur
IS
l_refcur dynamic_refcur;
l_stmt_str VARCHAR2(2000) := NULL;
BEGIN
IF p_group_type = 'S' THEN
-- join A and B
OPEN l_refcur FOR
SELECT ...
FROM A, B
WHERE A.x = B.y;
ELSE -- p_group_type = 'D'
SELECT resolved_query
INTO l_stmt_str
FROM dynamic_message_group_query
WHERE group_number = p_group_number;
-- join A, C and D (= dynamically created SELECT)
OPEN l_refcur FOR
'SELECT ...
FROM A, C, (' || l_stmt_str || ') D
WHERE A.x = C.y
AND A.z = D.t';
END IF;
RETURN l_refcur;
END;
END; Regards,
Zlatko -
Hi Folks,
When i try to run the following piece of code i get errors saying :
PLS-0221 : emp_cursor is not a procedure or is undefined
PLS-00382 : expression is of the wrong type
can you please help me figure out what is going wrong here ?
Thanks very much in advance.
Moses.
declare
/* REF Cursor for employee */
emp_rec employee%ROWTYPE;
TYPE EmpCurTyp IS REF CURSOR RETURN emp_rec%TYPE;
emp_cursor EmpCurTyp;
emp_id NUMBER;
cursor dept_cursor is
select distinct dept_id from dept;
dept_rec dept_cursor%ROWTYPE;
dep_id VARCHAR2(20);
begin
/* dept loop */
for dept_rec in dept_cursor
loop
dep_id := dept_rec.dept_id;
/* get employees for this dept */
OPEN emp_cursor FOR
select distinct emp_id from employee
where dept_id = dep_id;
/* employee loop */
for emp_rec in emp_cursor
loop
emp_id := emp_rec.employee_id;
'Hi Moses,
looking at Yr code, I guess that the problem may be that You OPEN emp_cursor and after that You reopen the same cursor with the FOR statement.
Try rewriting the LOOP in this way:
OPEN emp_cursor FOR
SELECT DISTINCT emp_id
FROM employee
WHERE dept_id = dep_id;
FETCH emp_cursor INTO emp_record
WHILE emp_cursor%FOUND
LOOP
-- Yr code here
FETCH emp_cursor INTO emp_record;
END LOOP;
CLOSE emp_cursor;You can also convert the usage of the REF syntax using cursor variables.
Hope thi helps
Bye Max
null -
Help on CAST function, defining TYPE TABLE and using a REF cursor
Hi,
I have written a procedure (lookup) inside a package (lookup_pkg) as shown below.
Procedure has an output variable of type PL/SQL TABLE which is defined in the package.
I want to write a wrapper procedure lookupref to the procedure lookup to return a ref cursor.
CREATE OR REPLACE PACKAGE lookup_pkg AS
TYPE t_lookup_refcur IS REF CURSOR;
CURSOR c_lookup IS
Select columns1,2,3,....100
FROM A, B, C, D, E
WHERE ROWNUM < 1;
TYPE t_lookup IS TABLE OF c_lookup%ROWTYPE;
Procedure lookup(id Number, o_lookup OUT t_lookup);
End lookup_pkg;
CREATE OR REPLACE PACKAGE BODY lookup_pkg As
Procedure lookup(id Number, o_lookup OUT t_lookup) IS
BEGIN
END lookup;
Procedure lookupref(id Number, o_lookupref OUT t_lookup_refcur) IS
o_lookup t_lookup;
BEGIN
lookup(id, o_lookup t_lookup);
OPEN t_lookup_refcur FOR
SELECT *
FROM TABLE(CAST(o_lookup AS t_lookup));
Exception
End lookupref;
END lookup_pkg;
When I compile this procedure, I am getting invalid datatype Oracle error and
cursor points the datatype t_lookup in the CAST function.
1. Can anyone tell me what is wrong in this. Can I convert a PL/SQL collection (pl/sql table in this case) to PL/SQL datatype table or does it need to be a SQL datatype only (which is created as a type in database).
Also, to resolve this error, I have created a SQL type and table type instead of PL/SQL table in the package as shown below.
create or replace type t_lookuprec as object
(Select columns1,2,3,....100
FROM A, B, C, D, E
WHERE ROWNUM < 1);
create or replace type t_lookup_tab AS table of t_lookuprec;
CREATE OR REPLACE PACKAGE BODY lookup_pkg As
Procedure lookup(id Number, o_lookup OUT t_lookup) IS
BEGIN
END lookup;
Procedure lookupref(id Number, o_lookupref OUT t_lookup_refcur) IS
o_lookup t_lookup;
BEGIN
lookup(id, o_lookup t_lookup);
OPEN t_lookup_refcur FOR
SELECT *
FROM TABLE(CAST(o_lookup AS t_lookup_tab));
Exception
End lookupref;
END lookup_pkg;
When I compile this package, I am getting "PL/SQL: ORA-22800: invalid user-defined type" Oracle error and
points the datatype t_lookup_tab in the CAST function.
2. Can anyone tell me what is wrong. Can I create a type with a select statement and create a table type using type created earlier?
I have checked the all_types view and found that
value for Incomplete column for these two types are YES.
3. What does that mean?
Any suggestions and help is appreciated.
Thanks
Srinivascreate or replace type t_lookuprec as object
(Select columns1,2,3,....100
FROM A, B, C, D, E
WHERE ROWNUM < 1);You are correct that you need to use CREATE TYPE to use the type in SQL.
However unless I am mistaken you appear to have invented your own syntax for CREATE TYPE, suggest you refer to Oracle documentation. -
Hi all,
I m creating a table dynamically and after that i m inserting records in tht table dynamically..
After tht i want to fetch all the records from tht table into a cursor which is a SYS_REFCURSOR. as i have to return the data to frntend ..
But when i m opening tht cursor like
OPEN cur_GetCertDetails
FOR
SELECT TRIM(certrefno) As CertNo,
TRIM(damagedno) As Damagedno,
TRIM(personname) As Name,
TRIM(icnumber) As Icnumber,
TRIM(coursename) As CourseName,
TRIM(organiser) As Organiser,
TRIM(location) As Location,
TRIM(TO_CHAR(startdate,'DD-MON-YYYY') ||' ~ '||
TO_CHAR(enddate,'DD-MON-YYYY')) As StartEndDate
FROM ACprintInductionCert;
Its giving error as
64/5 PL/SQL: SQL Statement ignored
73/10 PL/SQL: ORA-00942: table or view does not exist
Dynamically created table name is ACprintInductionCert
Pls help me out ..
I have tried to use EXECUTE IMMEDIATE after FOR but its givin errsince your table is created dynamically, you can not
have the name hardcoded in the cursor....which is precisely the point (or one of them) I made in your Procedure Problem Urgent on this topic.
Once you start down the road of dynamic code execution it is very difficult to stop. Dynamic code has its uses but it should be very much the last resort. Dynamic code means you are literally running untested code in a production environment, and is consequently more likely to fail. Its failures are also more difficult to recover from. It also makes dependency tracking extremely difficult.
Cheers, APC -
Need Urgent Help Reports 6i : Ref Cursor
Hi,
I am creating required SQL for report in my Java program. I want to pass this SQL stmt to my Oracle Report.
For that , I am storing the SQL stmt in Oracle table and then I want to use that stmt with few additions to fetch data . Is there any good method other than Ref Cursor to do this? Somehow Ref cursor is not working in Reports 6i. Or may be I don't know how to use it.
Any help will be appreciated !!
VMJLexical parameters seem to be much more appropriate tool for this task. You can create entire query as single lexical parameter, and script it in the After Parameter Form trigger any way you need. Just make sure to supply some dummy query as initial value for the lexical parameter, so that the report could create proper data structure.
-
Need help about ref cursor using like table
Hi Guys...
I am devloping package function And i need help about cursor
One of my function return sys_refcursor. And the return cursor need to be
join another table in database . I don't have to fetch all rows in cursor
All i need to join ref cursor and another table in sql clause
like below
select a.aa , b.cc form ( ref_cursor ) A, table B
where A.dd = B.dd
I appeciate it in advanceMy understanding is that you have a function that returns a refcursor and is called by a java app.
Because this is a commonly used bit of code, you also want to reuse this cursor in other bits of sql and so you want to include it like table in a bit of sql and join that refcursor to other tables.
It's not as easy as you might hope but you can probably achieve this with pipelined functions.
Is it a direction that code should be going down? yes, eventually. I like the idea of pulling commonly used bits of code into a SQL statement especially into the WITH section, provided it could be used efficiently by the CBO.
Is it worth the effort given what you have to do currently to implement it? possibly not.
what else could you do? construct the sql statement independently of the thing that used it and reuse that sql statement rather than the refcursor it returns?
Message was edited by:
dombrooks -
I have a stored procedure that returns a weak REF CURSOR as an out parameter. I want to access the rows that are returned, in an OCI application. I want a sample OCI program that does this. The PL/SQL code is as follows
PACKAGE TEST_PACKAGE AS
TYPE RCT IS REF CURSOR;
END;
PROCEDURE TEST_PROCEDURE (R OUT TEST_PACKAGE.RCT)
AS
BEGIN
OPEN r FOR
SELECT * FROM XXX;
END;
THANKS.Hello,
I used in my application regular connections, I created
CallableStatement with these connections, later I got one cursor with:
mr = ((OracleCallableStatement)cstmt).getCursor(1)
where mr is ResultSet and cstmt is CallableStatement.
But, when I use the Commerce PoolConnection I get serialConnection
and it creates serialCallableStatement and the command:
mr = ((OracleCallableStatement)cstmt).getCursor(1)
get the next exception:
java.lang.ClassCastException:
weblogic.jdbc20.rmi.SerialCallableStatement at......
Are you working with Bea ConnectionPool
or regular Connections?
Thank you.
<BLOCKQUOTE><font size="1" face="Verdana, Arial">quote:</font><HR>Originally posted by Matt Sivertson ([email protected]):
I'm having a very strange problem with some JDBC code. Basically, there is a StoredProcedure in the DB that we call through JDBC. One of the out parameters is a REF CURSOR. My user does not have select access to the table, but the stored procedure does. When I try and get the ResultSet corresponding to that RefCursor using the OracleCallableStatement.getCursor() method, and exception gets thrown saying it cannot find the table. We checked on the database, and it is actually performing a new select statement as My user, rather than as the StoredProcedure. If we open up the permissions on the table, everything works fine, but this defeats the whole purpose of what the DBA wants.
BTW, this same Stored Procedure works when fine when accesed through PL/SQL or SQL+. Only JDBC seems to have a problem with it. Any help is greatly appreciated.
Matt Sivertson
[email protected]<HR></BLOCKQUOTE>
null -
PLS-00428 Why SELECT must be adorned with REF CURSOR to work?
hello
*"PLS-00428: an INTO clause is expected in this SELECT statement"* - This problem has been resolved. I just want to understand WHY SELECT statements need to be paired with REF CURSOR.
To reproduce this,
DECLARE
Id1 numeric(19,0);
Id2 numeric(19,0);
CreateTimestamp date;
BEGIN
-- ATTN: You'd either need to select into variable or open cursor!
select * from SystemUser left join Person on Person.Id = SystemUser.PersonId WHERE Person.PrimaryEmail in ('[email protected]','[email protected]');
END;
Solution?
* In install script:
CREATE OR REPLACE PACKAGE types
AS
TYPE cursorType IS REF CURSOR;
END;
* Then in your query:
DECLARE
Id1 numeric(19,0);
Id2 numeric(19,0);
Result_cursor types.cursorType;
BEGIN
OPEN Result_cursor FOR select * from SystemUser left join Person on Person.Id = SystemUser.PersonId WHERE Person.PrimaryEmail in ('[email protected]','[email protected]');
END;
I Googled for reasonable explaination - closest is: http://www.tek-tips.com/viewthread.cfm?qid=1338078&page=34
That in oracle block or procedures are expected to do something and a simple SELECT is not!! (Very counter intuitive). What needs to be done is therefore to put the select output into a ref-cursor to fool oracle so that it thinks the procedure/block is actually doing something. Is this explanation right? Sounds more like an assertion than actually explaining...
Any suggestion please? Thanks!Opening a cursor (ref cursor or otherwise) is not the same as executing a select statement.
A select statement returns data, so if you are using it inside PL/SQL code it has to return that data into something i.e. a local variable or structure. You can't just select without a place for the data to go.
Opening a cursor issues the query against the database and provides a pointer (the ref cursor), but at that point, no data has been retrieved. The pointer can then be used or passed to some other procedure or code etc. so that it may then fetch the data into a variable or structure as required.
It's not counter-intuitive at all. It's very intuitive. -
"java.sql.SQLException: Ref cursor is invalid" - Please help
Hi everyone,
I'm really having problem. I'm surrently calling a PL/SQL stored procedure from Java but I'm getting the following error:
java.sql.SQLException: Ref cursor is invalid
The procedure has 2 normal IN parameters and 1 ref cursor OUT parameter. Depending upon Parameter 1 a ref cursor may or may not be initialised.
If Parameter 1 is "yes" then a ref cursor is called to retrieve some data and passed into the OUT. If Parameter 1 is set to "no" then the ref cursor is not initialised. It is here where the error is being hrown. Does anyone know why? Microsoft ADO doesn't seem to complain. Please help is needed. Thanks in advance.
JohnHi Justin,
Thanks for replying. The Java code is a bit awkward to send because we're using several "home-made" wrapper objects to call SQL and stored procedures. In both cases I create a resultset object and only this one object is used irrespective if the first parameter is "yes" or "no", but a ref cursor is passed to the OUT parameter only on condition yes. Hence, the PL/SQL code takes the form similar to:
OPEN curs FOR SELECT * FROM table;
The "curs" is then put into the OUT of the procedure. When the parameter is "no" then the "curs" ref cursor in the PL/SQL procedure isn't even initialised like the above. At this point Java complains of an invalid ref cursor. I can try and piece togather the code but it may be very tricky.
John -
I am tryin to create a procedure with ref cursor. It is giving error message like
PLS-00201:identifier 'TYPES>CURSOR_TYPE' must be declared.
Any idea how to resolve this error.
CREATE OR REPLACE PROCEDURE "PROC_GET_USERNAME" (
p_user_name IN bmf_users_temp.user_name%TYPE,
p_recordset OUT TYPES.cursor_type --"SYS_REFCURSOR"
AS
BEGIN
OPEN p_recordset FOR
select first_name ||' ' || last_name ||' '|| bmf_user_type ||' '||
bmf_user_role || ' ' ||bmf_user_status from bmf_users_temp ab where
user_name=p_user_name and
bmf_user_status='A';
WHEN NO_DATA_FOUND
THEN
NULL;
END PROC_GET_USERNAME;
/I guess TYPES is a package in which you have declared cursor_type as a sys_refcursor.
1. Please check the package if it has cursor_type declared as the same spelling.
2. Check if current user have the select rights of the package TYPES.
Regards
G -
Dear All,
Version : '11.2.0.2.0'
I have a procedure which gets called from a screen ( on .Net) if use pushes a particular button.
The procedure takes 15 minutes to complete.
My requirement is to intimate the front end(.Net) as soon as the procedures gets called successfully without waiting for its completion as it is going to take 15 mins.
The reason being, the front end will popup a message saying that " The process is going to take long time, A mail will be sent to u after its completion" once it has been intimated that the procedure has been called successfully.
Could you please suggest can i return a cursor to front end without even manipulating the data.
i hope my question is understandable.9876564 wrote:
Dear All,
Version : '11.2.0.2.0'
I have a procedure which gets called from a screen ( on .Net) if use pushes a particular button.
The procedure takes 15 minutes to complete.
My requirement is to intimate the front end(.Net) as soon as the procedures gets called successfully without waiting for its completion as it is going to take 15 mins.
The reason being, the front end will popup a message saying that " The process is going to take long time, A mail will be sent to u after its completion" once it has been intimated that the procedure has been called successfully.
Could you please suggest can i return a cursor to front end without even manipulating the data.
i hope my question is understandable.
It seems to me that your problem is not an Oracle one, but a user interface one.
I'm assuming the slowness of the procedure is due to how long it's taking to query the data, and if you can't speed that up then, to have the procedure return a ref cursor, the connection between the front end and the procedure must be maintained (the process on Oracle must belong to a session, and the front end needs to be connected to that session).
So, you can't have Oracle go off and start a seperate process and then pass back the ref cursor when it's finished, because even though you can spawn off seperate processes such as using DBMS_JOB or DBMS_SCHEDULER, they will run in their own 'session' and the calling code won't keep a hold on any of those sessions... they're effectively stand-alone and seperate.
What you'll have to do is likely get your .net application to spawn off a child process to the main app, that presents the message saying it'll take some time, does the call to Oracle and waits for Oracle to return the resultant ref cursor, which it can then pass back to the main application etc. Due to .net allowing for multi-tasking, that is where the split processing should take place. -
ORA-01008 with ref cursor and dynamic sql
When I run the follwing procedure:
variable x refcursor
set autoprint on
begin
Crosstab.pivot(p_max_cols => 4,
p_query => 'select job, count(*) cnt, deptno, row_number() over (partition by job order by deptno) rn from scott.emp group by job, deptno',
p_anchor => Crosstab.array('JOB'),
p_pivot => Crosstab.array('DEPTNO', 'CNT'),
p_cursor => :x );
end;I get the following error:
^----------------
Statement Ignored
set autoprint on
begin
adsmgr.Crosstab.pivot(p_max_cols => 4,
p_query => 'select job, count(*) cnt, deptno, row_number() over (partition by
p_anchor => adsmgr.Crosstab.array('JOB'),
p_pivot => adsmgr.Crosstab.array('DEPTNO', 'CNT'),
p_cursor => :x );
end;
ORA-01008: not all variables bound
I am running this on a stored procedure as follows:
create or replace package Crosstab
as
type refcursor is ref cursor;
type array is table of varchar2(30);
procedure pivot( p_max_cols in number default null,
p_max_cols_query in varchar2 default null,
p_query in varchar2,
p_anchor in array,
p_pivot in array,
p_cursor in out refcursor );
end;
create or replace package body Crosstab
as
procedure pivot( p_max_cols in number default null,
p_max_cols_query in varchar2 default null,
p_query in varchar2,
p_anchor in array,
p_pivot in array,
p_cursor in out refcursor )
as
l_max_cols number;
l_query long;
l_cnames array;
begin
-- figure out the number of columns we must support
-- we either KNOW this or we have a query that can tell us
if ( p_max_cols is not null )
then
l_max_cols := p_max_cols;
elsif ( p_max_cols_query is not null )
then
execute immediate p_max_cols_query into l_max_cols;
else
RAISE_APPLICATION_ERROR(-20001, 'Cannot figure out max cols');
end if;
-- Now, construct the query that can answer the question for us...
-- start with the C1, C2, ... CX columns:
l_query := 'select ';
for i in 1 .. p_anchor.count
loop
l_query := l_query || p_anchor(i) || ',';
end loop;
-- Now add in the C{x+1}... CN columns to be pivoted:
-- the format is "max(decode(rn,1,C{X+1},null)) cx+1_1"
for i in 1 .. l_max_cols
loop
for j in 1 .. p_pivot.count
loop
l_query := l_query ||
'max(decode(rn,'||i||','||
p_pivot(j)||',null)) ' ||
p_pivot(j) || '_' || i || ',';
end loop;
end loop;
-- Now just add in the original query
l_query := rtrim(l_query,',')||' from ( '||p_query||') group by ';
-- and then the group by columns...
for i in 1 .. p_anchor.count
loop
l_query := l_query || p_anchor(i) || ',';
end loop;
l_query := rtrim(l_query,',');
-- and return it
execute immediate 'alter session set cursor_sharing=force';
open p_cursor for l_query;
execute immediate 'alter session set cursor_sharing=exact';
end;
end;
/I can see from the error message that it is ignoring the x declaration, I assume it is because it does not recognise the type refcursor from the procedure.
How do I get it to recognise this?
Thank you in advanceThank you for your help
This is the version of Oracle I am running, so this may have something to do with that.
Oracle9i Enterprise Edition Release 9.2.0.8.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.8.0 - Production
I found this on Ask Tom (http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:3027089372477)
Hello, Tom.
I have one bind variable in a dynamic SQL expression.
When I open cursor for this sql, it gets me to ora-01008.
Please consider:
Connected to:
Oracle8i Enterprise Edition Release 8.1.7.4.1 - Production
JServer Release 8.1.7.4.1 - Production
SQL> declare
2 type cur is ref cursor;
3 res cur;
4 begin
5 open res for
6 'select * from (select * from dual where :p = 1) connect by 1 = 1'
7 using 1;
8 end;
9 /
declare
ERROR at line 1:
ORA-01008: not all variables bound
ORA-06512: at line 5
SQL> declare
2 type cur is ref cursor;
3 res cur;
4 begin
5 open res for
6 'select * from (select * from dual where :p = 1) connect by 1 = 1'
7 using 1, 2;
8 end;
9 /
PL/SQL procedure successfully completed.
And if I run the same thing on 10g -- all goes conversely. The first part runs ok, and the second
part reports "ORA-01006: bind variable does not exist" (as it should be, I think). Remember, there
is ONE bind variable in sql, not two. Is it a bug in 8i?
What should we do to avoid this error running the same plsql program code on different Oracle
versions?
P.S. Thank you for your invaluable work on this site.
Followup June 9, 2005 - 6pm US/Eastern:
what is the purpose of this query really?
but it would appear to be a bug in 8i (since it should need but one). You will have to work that
via support. I changed the type to tarray to see if the reserved word was causing a problem.
variable v_refcursor refcursor;
set autoprint on;
begin
crosstab.pivot (p_max_cols => 4,
p_query =>
'SELECT job, COUNT (*) cnt, deptno, ' ||
' ROW_NUMBER () OVER ( ' ||
' PARTITION BY job ' ||
' ORDER BY deptno) rn ' ||
'FROM emp ' ||
'GROUP BY job, deptno',
p_anchor => crosstab.tarray ('JOB'),
p_pivot => crosstab.tarray ('DEPTNO', 'CNT'),
p_cursor => :v_refcursor);
end;
/Was going to use this package as a stored procedure in forms but I not sure it's going to work now.
Maybe you are looking for
-
AutoAdjustment in progress message keeps flashing on my screen
I have tried the suggestion to switch off the power to my monitor & hold down the on/off button for 30-60 seconds, but this did not solve the problem.Also I cannot get the Management Screen to appear when I press the button & so cannot get to restore
-
Hi everyone i m getting a problem while connecting to MS-Access thru ODBC in forms, using EXEC_SQL Pkg its giving me a message Frm-40734:internal error. the error is at line EXEC_SQL.OPEN_CONNECTION(/@odbc:conac) where "conac" is the ODBC connection
-
Creating a complex query in CR designer
I'm running Crystal Reports XI Release 2 on Windows NT. I have a very complex query and cannot figure out how to make it work in CR. Basically, I've got a table A with fields containing reference codes that may or may not be present. I created a SQL
-
Using the output of one layer as an alpha channel for another
I was messing around last night trying to create my own sharpen edges filter. I duplicated a nested layer, applied find edges to the top one, then used the track matte filter on the one below, set the layer above as the target for the effect, and ch
-
I have this error and don't understand exactly what it means. Any advice on where to look to research it? I tried typing in the exception itself and even wrapper, but am not getting anything that explains to me why it happened and how to fix it. [cod