... as ever ... :-))
Klaus, March 12, 2002 - 7:53 am UTC
again hi Tom ...
you made my day and saved me lot's of time/troubles ...
next time in USA, I owe you a pint and a session pool ...
Thanks a lot!
What is the purpose of CURSOR?
AB, March 12, 2002 - 8:14 am UTC
Tom
I'm interested to know what is the purpose and intended use of the CURSOR expression and what types of application use is?
Thanks
March 12, 2002 - 4:43 pm UTC
It can be used to get "non-square" results from the database.
Say you wanted to run a single query to retrieve:
o a list of tables you owno all of their columns and datatypes
o the constraints on each table
o the list of users that have SELECT on it
o the list of roles that have SELECT on it
Well, you would have to run at least 3 and probably 4 queries to answer that normally.
with CURSOR -- you can run a single query that returns all of that in one query. You'll get a result set that contains 4 result sets for each row.
A reader, March 12, 2002 - 12:47 pm UTC
Tom,
Can you explain CURSOR in sql statement with REAL life
example ?. How we implement this functionality and in which cases we use this.
select deptno, dname, cursor( select ename from emp where emp.deptno = dept.deptno ) from dept
where deptno = p_deptno;
March 12, 2002 - 4:56 pm UTC
the original questioner had a REAL WORLD example ...
The retrieved a user, all of their contacts and all of their addresses.
Normally, you would run a query like this:
for x in ( select * from users )
loop
for y in ( select * from contacts where userid=x.userid )
loop
...
end loop;
for z in ( select * from addresses where userid=x.userid )
loop
...
end loop;
end loop;
Their query does all of that in a single query -- instead of incurring the overhead of running two queries / row, you just get a row with two result sets that you can fetch from.
the next logical question is...
Scott Mattes, March 12, 2002 - 9:04 pm UTC
Tom,
How does one code PL/SQL to fetch from this cursor?
March 13, 2002 - 7:06 am UTC
it is not useful in PLSQL as yet. It is useful for returning results back to a client like Java or C.
Sorry to labour this one....
Adrian Billington, March 13, 2002 - 4:06 am UTC
Tom
Like Scott, I'd also be interested to know if we could cycle through this statement in PL/SQL. Furthermore, what can you actually do with the resultset once you have it - it seems to me as though you can read it but not do much else with it unless there are some tricks to referencing the various cursor resultsets...?
Thanks
Adrian
March 13, 2002 - 7:18 am UTC
In java or C, you'll get cursors (result sets) that you can read (thats what we do with resultsets?). You can iterate over them and do whatever you please.
PLSQL, unaware of this construct, cannot use them (yet)
More please
A reader, March 13, 2002 - 9:51 am UTC
Hi,
As Scott and Adrian addressed, how we reference the portion of "nested cursor" when we pass the REF cursor result set back to JAVA or C program?
Please give little example?
Thanks
March 13, 2002 - 11:22 am UTC
$ java RefCursor
ACCOUNTING
CLARK
KING
MILLER
RESEARCH
SMITH
JONES
SCOTT
ADAMS
FORD
SALES
ALLEN
WARD
MARTIN
BLAKE
TURNER
JAMES
OPERATIONS
$ cat RefCursor.java
import java.sql.*;
import java.io.*;
import oracle.jdbc.driver.*;
class RefCursor
{
public static void main (String args [])
throws SQLException, ClassNotFoundException
{
String query = "begin "+
"open ? for "+
"'select dname, CURSOR(select ename "+
"from emp "+
"where emp.deptno=dept.deptno) "+
"from dept'; "+
"end;";
DriverManager.registerDriver
(new oracle.jdbc.driver.OracleDriver());
Connection conn=
DriverManager.getConnection
("jdbc:oracle:thin:@aria-dev:1521:ora817dev",
"scott", "tiger");
Statement trace = conn.createStatement();
CallableStatement cstmt = conn.prepareCall(query);
cstmt.registerOutParameter(1,OracleTypes.CURSOR);
cstmt.execute();
ResultSet rset= (ResultSet)cstmt.getObject(1);
for(int i = 0; rset.next(); i++ )
{
System.out.println( rset.getString(1) );
ResultSet rset2 = (ResultSet)rset.getObject(2);
for( int j = 0; rset2.next(); j++ )
System.out.println( " " + rset2.getString(1) );
rset2.close();
}
rset.close();
cstmt.close();
}
}
OK, how about an example in some other language?
Scott Mattes, March 13, 2002 - 10:39 am UTC
First, are there plans for PL/SQL to be able to use this?
Second, would you give an example in Delphi, JAVA or C for using this, I am way curious.
March 13, 2002 - 11:42 am UTC
yes, there are.
See java above. No idea about "delphi", you'd have to ask them.
A reader, March 13, 2002 - 4:36 pm UTC
Tom,
I can get same results by joing tables. What's new in
CURSOR subqueries?
March 13, 2002 - 6:44 pm UTC
Look at the second comment on this page "What is the purpose of CURSOR? " and my response to it. Now, write me a single query using only joins that gets me that data without using CURSOR (hint -- there is in fact a way to do it HOWEVER it in itself involves using Object types!)
calling the given PL/SQL Function from java/PHP -> ORA 6503
Klaus, March 14, 2002 - 7:54 am UTC
Hi Tom,
Based on your response I adapted my PL/SQL Function and it could be compiled successfully!
Unfortunately I'll get ORA 6503, when I try to execute the function, for e.g. with the following Java Code ...
String query = "begin ? := DSS.getUser(1); end;";
DriverManager.registerDriver(
new oracle.jdbc.driver.OracleDriver());
conn = DriverManager.getConnection("jdbc:oracle:oci8:@tstDB", "username", "password");
CallableStatement cstmt = conn.prepareCall(query);
cstmt.registerOutParameter(1,OracleTypes.CURSOR);
cstmt.execute();
ResultSet rset= (ResultSet)cstmt.getObject(1);
for (int i = 0; rset.next(); i++) {
System.out.println("UId ="+rset.getString(1));
System.out.println("Login ="+rset.getString(2));
System.out.println("Passwd="+rset.getString(3));
System.out.println("FName ="+rset.getString(4));
System.out.println("SName ="+rset.getString(5));
ResultSet rset2 = (ResultSet) rset.getObject(12);
for (int j = 0; rset2.next(); j++) {
System.out.println(" ContactId="+rset2.getString(1));
}
rset2.close();
ResultSet rset3 = (ResultSet) rset.getObject(13);
for (int j = 0; rset3.next(); j++) {
System.out.println(" AddressId="+rset3.getString(1));
}
rset3.close();
}
rset.close();
cstmt.close();
conn.close();
The query in the PL/SQL Function works properly and delivers a record, if executed in SQL-Plus or other tool!
FollowUp-Question from me is, how to retrieve the refCursor
from the function?
Thanks again for your help!
March 14, 2002 - 8:29 am UTC
well, one would need to see the PLSQL code as the error is coming from there!
Based on the error:
$ oerr ora 6503
06503, 00000, "PL/SQL: Function returned without value"
// *Cause: A call to PL/SQL function completed, but no RETURN statement was
// executed.
// *Action: Rewrite PL/SQL function, making sure that it always returns
// a value of a proper type.
I would GUESS that you are forgetting to return the ref cursor in the function!
You retrieve the ref cursor from the function in exactly the way I demonstrated above with the anonymous block -- it is not any different whatsoever. You would change:
String query = "begin "+
"open ? for "+
"'select dname, CURSOR(select ename "+
"from emp "+
"where emp.deptno=dept.deptno) "+
"from dept'; "+
"end;";
to
String query = "begin ? := f(); end;";
and thats it.
forgotten PL/SQL Function Code
Klaus UNGER, March 14, 2002 - 9:14 am UTC
Hi Tom,
Sorry about forgetting the function source ...
refCursor ist defined as follows in the package:
TYPE refCursor IS REF CURSOR;
here is the source - as I'm returning the cursor, I got worried about the ref Cursor declaration ...
FUNCTION getUser(pUserId Users.UserId%TYPE)
RETURN refCursor
IS
c refCursor;
BEGIN
OPEN c FOR
'SELECT U.UserId, U.LoginName, U.PassWord, U.ForeName, U.SureName, U.Gender, U.Description, ' ||
' U.ModDate, U.ModUser, DSCore.getState(U.State) AS State, U.DefaultLanguageId, ' ||
' CURSOR(SELECT C.UserContactId, DSS.getContactType(C.ContactTypeId) AS ContactType, ' ||
' C.Value, C.Description, DSCore.getState(C.State) AS State, C.ModUser ' ||
' FROM UserContacts C ' ||
' WHERE C.UserId = U.UserId) AS Contacts, ' ||
' CURSOR(SELECT A.UserAddressId, DSS.getAddressType(A.AddressTypeId) AS AddressType, ' ||
' A.StreetNo, A.ZipCode, A.City, A.Country, DSCore.getState(A.State) AS State, ' ||
' A.ModUser ' ||
' FROM UserAddresses A ' ||
' WHERE A.UserId = U.UserId) AS Addresses ' ||
'FROM Users U ' ||
'WHERE U.UserId = :UID' USING pUserId;
RETURN c;
EXCEPTION
WHEN OTHERS THEN
IF (c%isOpen) THEN
CLOSE c;
END IF;
END;
As I understand, I don't have to declare a Type, that specifies the structure of the result-set. If I have to,
I wouldn't know, how to declare a cursor in a record-type ...
So again ... please enlight me with your comments!
Many thanks in advance
Klaus
PS: pint-counter++; ... ;)
March 14, 2002 - 10:43 am UTC
You have the major #1 bug i the world.
"when others" that is not followed immediately by RAISE.
change the code to:
WHEN OTHERS THEN
IF (c%isOpen) THEN
CLOSE c;
END IF;
RAISE;
and then let us know what happens.
... done ...
Klaus UNGER, March 14, 2002 - 10:56 am UTC
Hi Tom,
before I go to self-flagellation for the stupid raise thing ... must be a kind of code-blindness ...
Thanks ... the raise brought to light, that dynamic SQL cannot handle bind-varibales like :UID. When I use :1 the procedure works properly ...
Thanks and sorry for any inconvenience
Klaus
March 14, 2002 - 11:09 am UTC
UID being one of those "magic words" ;)
ops$tkyte@ORA817DEV.US.ORACLE.COM> variable x refcursor
ops$tkyte@ORA817DEV.US.ORACLE.COM>
ops$tkyte@ORA817DEV.US.ORACLE.COM> begin
2 open :x for 'select :uid from dual' using 1;
3 end;
4 /
begin
*
ERROR at line 1:
ORA-01745: invalid host/bind variable name
ORA-06512: at line 2
ops$tkyte@ORA817DEV.US.ORACLE.COM> begin
2 open :x for 'select :user from dual' using 1;
3 end;
4 /
begin
*
ERROR at line 1:
ORA-01745: invalid host/bind variable name
ORA-06512: at line 2
ops$tkyte@ORA817DEV.US.ORACLE.COM> begin
2 open :x for 'select :bv_uid from dual' using 1;
3 end;
4 /
PL/SQL procedure successfully completed.
ops$tkyte@ORA817DEV.US.ORACLE.COM> print x
:BV_UID
----------
1
ops$tkyte@ORA817DEV.US.ORACLE.COM>
being a little bit embarrassed ...
Klaus, March 15, 2002 - 4:45 am UTC
Hi Tom ...
Thanks again,
Seems to be, that I was not programming PL/SQL for a bit too long ... forget about all "minor details", which of course have huge impacts ...
- raise
- UID
back in college I'll give myself an failed ... ;)
Thanks & kind regards
Klaus
Very Informative......
Neeti, April 09, 2002 - 8:59 am UTC
I am not sure how many goddies are still hidden in your
treasure. That was cool. Can you point to the documentation
where I can find more information about this construct.
Thanks,
Neeti
April 09, 2002 - 9:15 am UTC
How about in 9i?
A reader, April 09, 2002 - 2:29 pm UTC
You mentioned 'it is not useful in PLSQL as yet. It is useful for returning
results back to a
client like Java or C.'
but things like the following code give may be perhaps usefull ?:
set serveroutput on
declare
type rctyp is ref cursor;
myrc1 rctyp;
myrc2 rctyp;
empno number;
deptno number;
ename varchar2(10);
begin
open myrc1 for select deptno,
cursor(select e.empno, e.ename
from emp e
where e.deptno = d.deptno)
from dept d;
fetch myrc1 into deptno, myrc2;
while myrc1%FOUND loop
dbms_output.put_line('deptno = ' || deptno);
fetch myrc2 into empno, ename;
while myrc2%FOUND loop
dbms_output.put_line('empno = ' || empno || ' ename = ' || ename);
fetch myrc2 into empno, ename;
end loop;
fetch myrc1 into deptno, myrc2;
end loop;
close myrc1;
end;
/
deptno = 10
empno = 7782 ename = CLARK
empno = 7839 ename = KING
empno = 7934 ename = MILLER
deptno = 20
empno = 7369 ename = SMITH
empno = 7566 ename = JONES
empno = 7788 ename = SCOTT
empno = 7876 ename = ADAMS
empno = 7902 ename = FORD
deptno = 30
empno = 7499 ename = ALLEN
empno = 7521 ename = WARD
empno = 7654 ename = MARTIN
empno = 7698 ename = BLAKE
empno = 7844 ename = TURNER
empno = 7900 ename = JAMES
deptno = 40
Cheers
Charly
April 09, 2002 - 2:40 pm UTC
Very nice, i tried binding to a dynamic ref cursor in 8i -- that didn't work. didn't think to try in 9i! I knew it was coming (thats why i said "yet" over and over).
Thanks!
How to do the Reverse
Siva, April 23, 2002 - 9:59 am UTC
It is useful for sending Ref Cursor from Sql to Java.
The same does not work in reverse.
I am parsing an XML in Java and converting into a sql statement. I would like to pass the REF cursor of this SQL to PL/SQL. How do I do This.
I tried something like this in Oracle 8.1.6 . Gives some Internal Error
-- The following would be in a Java Stored procedure
public static oracle.sql.REF getOracleResultset(String serviceResponse)
throws java.sql.SQLException {
-- This would be SQL I would construct from the xml
String sqlstmt = new String("select * From emp;");
System.out.println("Recieved serviceResponse");
Connection conn = new OracleDriver().defaultConnection();
CallableStatement cstmt = conn.prepareCall("begin open ? for "+sqlstmt+" end;");
cstmt.registerOutParameter(1, OracleTypes.CURSOR);
cstmt.execute();
REF refc = ((OracleCallableStatement)cstmt).getREF(1);
return refc;
}
April 23, 2002 - 10:57 am UTC
You cannot return a result set from a java stored procedure to plsql.
You can return the STRING that is the QUERY and let the SQL layer open a ref cursor.
Instead of:
return refc;
you will return sqlstmt;
Then the SQL layer (which you must go through regardless -- it is a layer you will be passing through anyway) can easily open that in a ref cursor.
Maximum open cursors exceeded when used with ORDER BY
Roger Andersson, June 24, 2002 - 9:53 am UTC
I use this technique for administration of users and their roles in one application. I return all users and all their roles in one select and it works fine, until I add an ORDER BY clause.
Then I get ORA-01000, maximum open cursors exceeded. I have open_cursors set to 100, which I know is too low, and my query returns, and will probably never return more than, approx 150 records.
I can probably increase open_cursors and use the select order by statement I need for my feature.
I want to know if there is a way to use these "embedded" cursor together with order by and resultsets with a couple of hundred up to 1000 records, without having open_cursors set very high? If so, how should the select statement look like? If not, do you have a suggestion for another technique that can be used to solve this in one select statement?
One simple testcase is to start with the Java code provided above, add a couple of hundred records to the dept table and add an order by dname to the select statement.
June 24, 2002 - 9:57 am UTC
The order by is adding some recursive sql (to allocate temp space or do something). It is not a function of the number of records (you would get it sorting 1 record or 1,000,000 records).
100 is way too low. I typically run with 1,000 to 1,500. We dynamically allocate the array 64 at a time so setting high does not have a high cost associated with it.
ORA-01008: not all variables bound
A reader, August 30, 2002 - 8:10 am UTC
Hi Tom
I followed your example and did this PL/SQL block but whenever I execute it I get ORA-01008, what´s wrong with my code?
DECLARE
type ref_cursor is ref cursor;
c1 ref_cursor;
cursor ch_cursor is select co_id, ch_seqno, ch_status, userlastmod, entdate
from contract_history ch1
where rownum = 1;
r_contract_histroy ch_cursor%rowtype;
fr_entdate CONSTANT DATE := trunc(sysdate - 7);
to_entdate CONSTANT DATE := trunc(sysdate - 1);
BEGIN
OPEN c1 for 'select co_id, ch_seqno, ch_status, userlastmod, entdate
from (select co_id, ch_seqno, ch_status, userlastmod, entdate,
dense_rank() over (partition by co_id order by ch_seqno desc) rango
from contract_history
where co_id < 11
and trunc(entdate) <= :to_entdate) iv_ch
where rango = 1
or (ch_seqno = 1 and trunc(entdate) <= :to_entdate)
order by co_id, ch_seqno' USING to_entdate;
LOOP
FETCH c1 into r_contract_histroy;
EXIT when c1%notfound;
dbms_output.put_line(r_contract_histroy.co_id);
END LOOP;
CLOSE c1;
END;
/
ERROR at line 1:
ORA-01008: not all variables bound
ORA-06512: at line 11
August 30, 2002 - 10:23 am UTC
using to_entdate, to_entdate;
You have two bind variables, only one of which was bound.
ops$tkyte@ORA920.US.ORACLE.COM> variable x refcursor
ops$tkyte@ORA920.US.ORACLE.COM> set autoprint on
ops$tkyte@ORA920.US.ORACLE.COM>
ops$tkyte@ORA920.US.ORACLE.COM> begin
2 open :x for 'select :y, :y from dual' using 'Hello';
3 end;
4 /
begin
*
ERROR at line 1:
ORA-01008: not all variables bound
ORA-06512: at line 2
ERROR:
ORA-24338: statement handle not executed
SP2-0625: Error printing variable "x"
Elapsed: 00:00:00.00
ops$tkyte@ORA920.US.ORACLE.COM>
ops$tkyte@ORA920.US.ORACLE.COM> begin
2 open :x for 'select :y, :y from dual' using 'Hello', 'World';
3 end;
4 /
PL/SQL procedure successfully completed.
:Y :Y
-------------------------------- --------------------------------
Hello World
Elapsed: 00:00:00.00
ops$tkyte@ORA920.US.ORACLE.COM>
ORA-01008 I found error
A reader, August 30, 2002 - 8:18 am UTC
Hi
I noticved I have to put two variables
using to_Entdate, to_entdate
I thought if the variable names are equal I only have to put once...
cheers
Usage in 8.05
B.Harris, September 03, 2002 - 9:14 am UTC
Tom,
I'm unsure of how to implement in 8.0.5
ie. i want to return a ref cursor with embedded select using sql object type solution (due to ref cursor's not supporting dynamic sql)
i would like to
- create dynamic sql using embedded select (using dbms_sql)
then insert into collection type (sql object type)
- return as ref cursor
How would I implement define_column and column_value to insert into my object type?
Any workarounds/examples would be helpful?
September 03, 2002 - 9:30 am UTC
Not making sense to me. Not clear what you want -- but I would suggest saving it up for a QUESTION, not a review.
CURSOR
mo, December 24, 2002 - 10:32 am UTC
Tom:
You say using CURSOR makes things easier. However I still do not see it by running the example below. Any advantages of using this in pl/sql.
SQL> select deptno,dname,cursor(select ename from emp where emp.deptno = dept.deptno)
2 from dept where deptno = 10;
DEPTNO DNAME CURSOR(SELECTENAMEFR
---------- -------------- --------------------
10 ACCOUNTING CURSOR STATEMENT : 3
CURSOR STATEMENT : 3
ENAME
----------
CLARK
KING
MILLER
3 rows selected.
1 row selected.
1 select a.deptno,a.dname,b.ename from dept a, emp b where
2* a.deptno = b.deptno and b.deptno = 10
SQL> /
DEPTNO DNAME ENAME
---------- -------------- ----------
10 ACCOUNTING CLARK
10 ACCOUNTING KING
10 ACCOUNTING MILLER
3 rows selected.
December 24, 2002 - 12:21 pm UTC
where did I say it was easier?
It can be quite useful in many cases. Write me a query against
ALL_USERS, ALL_OBJECTS, ALL_TAB_PRIVS that returns:
a) a username
b) object names and their types owned by that user
c) all grants granted to that user
cursor
mo, December 24, 2002 - 2:29 pm UTC
Tom:
Do you mean this query:
select a.user_id,substr(a.username,1,10) username,
substr(b.owner,1,10) owner,substr(b.object_name,1,20) object_name,
substr(c.grantor,1,10) grantor,
substr(c.table_name,1,10) table_name,
substr(c.privilege,1,10) privilege
from all_users a,all_objects b, all_tab_privs c
where a.username=b.owner and b.owner=c.grantor
SQL> /
USER_ID USERNAME OWNER OBJECT_NAME GRANTOR TABLE_NAME PRIVILEGE
---------- ---------- ---------- -------------------- ---------- ---------- ----------
0 SYS SYS /1005bd30_LnkdConsta SYS DUAL SELECT
0 SYS SYS /10076b23_OraCustomD SYS DUAL SELECT
0 SYS SYS /1033c8a_SqlTypeWith SYS DUAL SELECT
0 SYS SYS /103a2e73_DefaultEdi SYS DUAL SELECT
0 SYS SYS /10501902_BasicFileC SYS DUAL SELECT
0 SYS SYS /106faabc_BasicTreeU SYS DUAL SELECT
0 SYS SYS /1079c94d_NumberCons SYS DUAL SELECT
0 SYS SYS /10804ae7_Constants SYS DUAL SELECT
0 SYS SYS /108343f6_MultiColor SYS DUAL SELECT
0 SYS SYS /10845320_TypeMapImp SYS DUAL SELECT
0 SYS SYS /10948dc3_Permission SYS DUAL SELECT
0 SYS SYS /1095ce9b_MultiCombo SYS DUAL SELECT
0 SYS SYS /109cbb8e_SpanShapeR SYS DUAL SELECT
0 SYS SYS /10a793fd_LocaleElem SYS DUAL SELECT
0 SYS SYS /10b74838_SecurityMa SYS DUAL SELECT
0 SYS SYS /10d0c623_drawBytesI SYS DUAL SELECT
0 SYS SYS /10dcd7b1_ProducerCo SYS DUAL SELECT
0 SYS SYS /10e48aa3_StringExpr SYS DUAL SELECT
December 24, 2002 - 2:46 pm UTC
yes and if you don't know what is wrong with that answer you gave, you need to pick up a book on SQL!!!
tell me, why is DUAL in there over and over and over and over -- why will /1005bd30_LnkdConsta appear in there over and over and over.
You have two 1:m relationships. A square result set isn't going to be very good for that.
Suppose you have a user SYS with 500 objects in all_objects and 50 grants in all_tab_privs. Do you really want 25000 records back for that user???
CURSOR
mo, December 24, 2002 - 3:14 pm UTC
well i mean if we have 1:m between user and objects and 1:m between user and grants then this should be the query. But it seems to be the same result. Are you saying you can not get the result you want with a join statement, and I have to use CURSOR.
1 select a.user_id,substr(a.username,1,10) username,
2 substr(b.owner,1,10) owner,substr(b.object_name,1,20) object_name,
3 substr(c.grantor,1,10) grantor,
4 substr(c.table_name,1,10) table_name,
5 substr(c.privilege,1,10) privilege
6 from all_users a,all_objects b, all_tab_privs c
7* where a.username=b.owner and a.username=c.grantor
SQL> /
USER_ID USERNAME OWNER OBJECT_NAME GRANTOR TABLE_NAME PRIVILEGE
---------- ---------- ---------- -------------------- ---------- ---------- ----------
0 SYS SYS /1005bd30_LnkdConsta SYS DUAL SELECT
0 SYS SYS /10076b23_OraCustomD SYS DUAL SELECT
0 SYS SYS /1033c8a_SqlTypeWith SYS DUAL SELECT
0 SYS SYS /103a2e73_DefaultEdi SYS DUAL SELECT
0 SYS SYS /10501902_BasicFileC SYS DUAL SELECT
Is this how you do it:
select username,cursor (select object_name,object_type from all_objects where object_type='TABL
cursor (select table_name,privilege from all_tab_privs) from all_users
where username='SYS'
SQL> /
USERNAME CURSOR(SELECTOBJECT_ CURSOR(SELECTTABLE_N
------------------------------ -------------------- --------------------
SYS CURSOR STATEMENT : 2 CURSOR STATEMENT : 3
CURSOR STATEMENT : 2
OBJECT_NAME OBJECT_TYPE
------------------------------ ------------------
ACCESS$ TABLE
AQ$_MESSAGE_TYPES TABLE
AQ$_PENDING_MESSAGES TABLE
AQ$_PROPAGATION_STATUS TABLE
AQ$_QUEUE_STATISTICS TABLE
AQ$_QUEUE_TABLE_AFFINITIES TABLE
AQ$_SCHEDULES TABLE
ARGUMENT$ TABLE
ASSOCIATION$ TABLE
ATEMPTAB$ TABLE
CURSOR STATEMENT : 3
TABLE_NAME PRIVILEGE
------------------------------ ----------------------------------------
DUAL SELECT
SYSTEM_PRIVILEGE_MAP SELECT
TABLE_PRIVILEGE_MAP SELECT
STMT_AUDIT_OPTION_MAP SELECT
STANDARD EXECUTE
V_$BH SELECT
V_$SESSION_LONGOPS SELECT
V_$NLS_PARAMETERS SELECT
V_$NLS_VALID_VALUES SELECT
V_$MLS_PARAMETERS SELECT
V_$OPTION SELECT
V_$VERSION SELECT
V_$PQ_SESSTAT SELECT
V_$SESSION_CONNECT_INFO SELECT
V_$PQ_TQSTAT SELECT
V_$ACTIVE_INSTANCES SELECT
December 24, 2002 - 4:25 pm UTC
I am saying you cannot get a meaningful, useful result with joins due to the two independent 1:m relationships
You would use a cursor() function in order to get something you can actually use.
CURSOR function
mo, December 26, 2002 - 10:17 am UTC
Tom:
1. I full understand now how CURSOR function can eliminate square results when you jon more than two tables. IS this SQL or oracle SQL*PLUS function only.
2. I noticed the the CURSOR function above, it is always doing an outer join even without using (+) in the join. Can you use CURSOR with inner join so that you can take out the wher ecaluse and print out only dept numbers that have employees in them.
3. does this have any use in using static sql in 8i pl/sql or only in 9i R2.
THanks,
December 26, 2002 - 11:54 am UTC
1) there are examples using plsql and java right above!
2) where exists... where in ... will do that.
3) using static sql in plsql *won't work* with this bit of functionality in 8i. In 9i and up -- go for it. In 8i, dynamic sql, views.
open q for query using a, b, c
Edgar Chupit, February 07, 2003 - 9:02 am UTC
Hello Tom,
ops$tkyte@ORA920.US.ORACLE.COM> begin
2 open :x for 'select :y, :y from dual' using 'Hello', 'World';
3 end;
4 /
I have a question about this, is it possible when I have query in varchar to find out how many and what are the names of bind variables?
Suppose I have a stored function that constructs sql query and returns ref cursor. My function have 3 params if each of params is not null than I add where condition. Is there a possibility to write code like that one without having to
write all possible combinations of params? It's just an example but I hope you'll get the point.
function test1( tbl varchar, log varchar, par varchar ) return refCur is
q varchar(512);
result refCur;
begin
q := 'SELECT TABLE_NAME, TABLESPACE_NAME '||chr(10)||
'FROM USER_TABLES '||chr(10)||
'WHERE MONITORING = ''NO'' '||chr(10);
if( tbl is not null ) then
q := q || 'AND TABLE_NAME LIKE :TBL '||chr(10);
end if;
if( log is not null ) then
q := q || 'AND LOGGING = :LOG '||chr(10);
end if;
if( par is not null ) then
q := q || 'AND PARTITIONED = :PAR'||chr(10);
end if;
if( tbl is null and log is null and par is null ) then
open result for q;
else if ( tbl is null and log is null and par is not null ) then
open result for q using par;
else if( tbl is null and log is not null and par is null ) then
open result for q using log;
else if( tbl is null and log is not null and par is not null ) then
open result for q using log, par;
else if( tbl is not null and log is null and par is null ) then
open result for q using tbl;
else if( tbl is not null and log is null and par is not null ) then
open result for q using tbl, par;
else if( tbl is not null and log is not null and par is null ) then
open result for q using tbl, log;
else if( tbl is not null and log is not null and par is not null ) then
open result for q using tbl, log, par;
end if; end if; end if; end if; end if; end if; end if; end if;
return result;
end;
February 07, 2003 - 12:22 pm UTC
awesome
Edgar Chupit, February 07, 2003 - 1:11 pm UTC
Hello Tom,
Thanks, really beautifull solution to use sys_context for this. Thanks!
problem with analytic function along with pl/sql table
MRL, February 25, 2003 - 10:59 am UTC
I have this scenario:
I need to join a pl/sql table inside a procedure with a database table and also use rank() function ...all these in the same query whose results are returned through a REF cursor.
Now analytic function HAS to be used in a dynamic query in pl/sql. But when i join the pl/sql table with the database table(in that dynamic query) i get an error as 'invalid column name'. The part of the query (with out the rank() )function works well as a normal (non-dynamic) query.
Here it is:
create or replace type obj_1 as object
(col1 varchar2(10),col2 varchar2(10);
/
create or replace type table_1 as table of obj_1;
/
/* not giving package specification here*/
create or replace package body pkg_p
as
create or replace package body prc_p
(comma_sep_string_1 in varchar2,
comma_sep_string_2 in varchar2,
ref_cur_var out ref_cur)
as
array_1 dbms_utility.uncl_array;
array_2 dbms_utility.uncl_array;
count_1 number;
count_2 number;
table_2 table_1:=table_1(obj_1('',''));
dbms_utility.comma_to_table(comma_sep_string_1,count_1 ,array_1);
dbms_utility.comma_to_table(comma_sep_string_2,count_2 ,array_2);
table_2 .extend(count_1-1,1);
for i in 1..count_1.count loop
table_2(i).col1:=array_1(i);
table_2(i).col2:=array_2(i);
end loop;
open ref_cur_var for
'select a1,b1,c1,rank() over (partition by a1 order by b1 desc) as myrank
from database_table,(select x.col1,x.col2 from TABLE(CAST(table_2 as table_1) as x ) pl_sql_table
where database_table.c1=pl_sql_table.col1';
end prc_p;
end pkg_p;
forgive me for syntax errors.
I get the error as 'invalid column name';
If i just return
select a1,b1,c1 from database_table,(select x.col1,x.col2 from TABLE(CAST(table_2 as table_1) as x ) pl_sql_table
where database_table.c1=pl_sql_table.c1
through the ref cursor (non dynamic query without rank()) it works fine.
But i need to include rank() and the join with pl/sql table...how do i do it?
Have i done a very silly mistake in the code????
I also need to do a myrank < 21 in the where clause .
how do i do it?
(i have read in this site before that using comma_to_table for such a cause is not correct)
February 25, 2003 - 7:51 pm UTC
you have to bind inputs -- this is the same as trying to bind a "date" into a query -- no different:
open ref_cur_var for
'select a1,b1,c1,rank() over (partition by a1 order by b1 desc) as myrank
from database_table,(select x.col1,x.col2 from TABLE(CAST( :x as table_1)
as x ) pl_sql_table
where database_table.c1=pl_sql_table.col1'
using table_2;
to get "myrank <21", you use an inline view
open ref_cur_var for
'select * from (
select a1,b1,c1,rank() over (partition by a1 order by b1 desc) as myrank
from database_table,(select x.col1,x.col2 from TABLE(CAST( :x as table_1)
as x ) pl_sql_table
where database_table.c1=pl_sql_table.col1 ) where myrank < 21'
using table_2;
cursor() in views
A reader, May 29, 2003 - 10:46 pm UTC
The OP's example (get user, all his contacts and all their addresses) is a great real-world example of CURSOR.
But when I try to create a view using a SELECT with a cursor() expression, I get ORA-22902 (cursor not allowed).
I really dont want to create 3 views (user, user_contacts, contact_address) for this! A user view with 2 CURSOR() columns would be perfect.
How can I work around this? Thanks
May 30, 2003 - 7:38 am UTC
i guess you won't be using a view -- perhaps a stored procedure that returns a ref cursor.
Recursive describe on the result set
Piotr Jarmuz, July 02, 2003 - 11:07 am UTC
Hello Tom,
Is there a way to do a recursive describe on the result set with the embedded cursors? I mean can I code:
public Node describe(ResultSetMetaData rs) throws Exception {
ResultSetMetaData md=rs.getMetaData();
for (int i=0; i<md.getColumnCount(); i++) {
if (md.getColumnType(i+1)==OracleTypes.CURSOR) {
// somehow get MetaData for this CURSOR
}
handle each other type
}
BEFORE I fetch actually the Cursor for the nested query?
I guess I can't but I'd like your confirmation.
My goal is to write a generic Java tree builder based on any SQL query also with embedded cursors.
I always can do that on the fly.
I though about it as an optimization to my builder.
Another associated problem:
Can I return an array of refcursors from a PL/SQL to the client? I tried the following in 9iR2 but it says:
declare
type cursor_array_t is table of sys_refcursor;
begin
...
end;
ORA-06550: line 2, column 24:
PLS-00990: Index Tables of Cursor Variables are disallowed
ORA-06550: line 2, column 1:
PL/SQL: Item ignored
It doesn't have to be an array. But I need a way to return an unknown number of cursors. I thought about embedded cursors built with execute immediate but maybe there is a simpler way?
Thanx a lot in advance!
July 02, 2003 - 11:13 am UTC
the "describe" in java is limited to describing result sets - hence you must retrieve the result set. so, you have to fetch a row in order to describe the result set contained in that row.
You cannot return an unknown number of ref cursors.
Why should we use RAISE in OTHERS exception?
Tony, April 16, 2004 - 2:31 am UTC
Tom,
Why should we use RAISE in OTHERS exception only?
Can you point to your answer for similar questions,if any, or some documents?
April 16, 2004 - 7:31 am UTC
what else are you going to do?
I know of one case where I use a when others without a RAISE
create function is_number( p_string in varchar2 ) return boolean
as
l_n number;
begin
l_n := p_string;
return true;
exceptions
when others then return false;
end;
but show me another legitimate case where "all errors should forthrightly be ignored"
WHEN OTHERS
Tony Andrews, April 16, 2004 - 8:43 am UTC
It fascinates me how often people code exception handlers like this one:
exception
when others then dbms_output.put_line (substr('Error: '||sqlerrm, 1, 249));
end;
(That is a real example posted as part of an answer in a forum yesterday.)
Clearly the writer intended that, should an error occur, it should be brought to the user's attention. What did he think would happen if he "forgot" to write that exception handler?!
April 16, 2004 - 9:10 am UTC
that's what I call ignoring the error and why I say "have a when others that is not followed by a RAISE is almost CERTAINLY a bug in your code"
imagine that exception block makes it into production.
that error will NEVER be seen from again, it'll will silently fail while appearing to succeed.
Ref Cursors in a function
Mohini, May 08, 2004 - 6:08 pm UTC
DBMS_OUTPUT.PUT_LINE (C_REC.EMPNO);
*
ERROR at line 4:
ORA-06550: line 4, column 29:
PLS-00302: component 'EMPNO' must be declared
ORA-06550: line 4, column 1:
PL/SQL: Statement ignored
May 10, 2004 - 7:21 am UTC
huh?
you might consider posting enough of an example for someone to comment on.
sorry for the bad cut-paste job
mohini, May 10, 2004 - 10:59 am UTC
CREATE PACKAGE MY_TYPES_PKG
AS
TYPE refCursor IS REF CURSOR;
END MY_TYPES_PKG;
/
CREATE FUNCTION GETEMPNAME
RETURN MY_TYPES_PKG.refCursor
IS
C MY_TYPES_PKG.refCursor;
BEGIN
OPEN C FOR
SELECT * FROM EMP;
RETURN C;
END;
/
SELECT GETEMPNAME FROM DUAL;
gives all the records
Now if I want to process the recordset as follows..I get an error:
set serveroutput on;
BEGIN
FOR C_REC IN (SELECT GETEMPNAME FROM DUAL) LOOP
DBMS_OUTPUT.PUT_LINE (C_REC.EMPNO);
END LOOP;
END;
/
DBMS_OUTPUT.PUT_LINE (C_REC.EMPNO);
*
ERROR at line 4:
ORA-06550: line 4, column 29:
PLS-00302: component 'EMPNO' must be declared
ORA-06550: line 4, column 1:
PL/SQL: Statement ignored
May 10, 2004 - 11:40 am UTC
did you ever think about what is happening here?
you have a query that returns a refcursor.
you do not have a query that returns a column name empno anywhere. You have an UNNAMED column that is a refcursor -- a result set. that result set might have EMPNO as a column, but c_rec sure doesn't.
In plsql, the way to do this is:
ops$tkyte@ORA9IR2> declare
2 l_cursor sys_refcursor;
3 l_rec emp%rowtype;
4 begin
5 l_cursor := getEmpName;
6 loop
7 fetch l_cursor into l_rec;
8 exit when l_cursor%notfound;
9 dbms_output.put_line( l_rec.empno );
10 end loop;
11 close l_cursor;
12 end;
13 /
7369
7499
7521
7566
7654
7698
7782
7788
7839
7844
7876
7900
7902
7934
PL/SQL procedure successfully completed.
bad cut-paste...
mohini, May 10, 2004 - 11:00 am UTC
Working in version 9.2.0.5 of oracle
Implicit vs Explicit
Mohini, May 10, 2004 - 2:07 pm UTC
9.2.0.5
Thanks Tom,
I was trying to process the cursor in one shot for loop..
instead of opening, closing it...
Thanks for the explanation.
questions:
1. FUNCTION GETEMPNAME can also be a procedure with an output variable.
Is there any advantage/disadvantage of doing it in a procedure rather than a function.
2. Can these weak refcursors be passed as a parameter into a procedure. Are there any caveats..
--Thanks
May 10, 2004 - 2:12 pm UTC
1) no
2) yes, but you sort of need to have known at compile time what their select lists where -- in order to have the necessary variables setup to fetch into.
PL/SQL Procedure returning a Ref-Cursor with "embedded Cursors
Sam Brown, June 28, 2004 - 7:00 am UTC
Found The arcticle Very useful. It has very good clear examples on how to create cursors and why you would use Cursors
Why this Error -- it is internal error -- but I am not sure if it is known bug.
Ajeet, October 14, 2004 - 7:03 am UTC
Hi Tom:
I have 2 oracle instances -- evnrdwq2 and evnctpq1 -
both of them are 9.2.0.5.
There is a table which is at evnrdwq2 --name is rdm_f_parameter. and then I have a public synonym of this table at evnctpq1 with the name rdo_parameter_value .
When I run this query at evnctpq1 -- I get the error as mentioned below :
select
cursor(select a.parameter_value
from rdo_parameter_value a
where a.param_seq_id = b.parameter_seq_id and a.dim_seq_id = b.dim_seq_id
and a.fleet = b.fleet and a.flight_datetime > sysdate-120 )
from
rdo.rdo_sea_alert_v b
/
Then I get the error :
ERROR at line 5:
ORA-00600: internal error code, arguments: [kokbnp2], [942], [], [], [], [],
[], []
When I run the query at evnrdwq2 -- using the rdm_f_parameter as it is at evnrdwq2 -then I do'nt get this error and it works fine.
select
cursor(select a.parameter_value
from rdm_f_parameter a
where a.param_seq_id = b.parameter_seq_id and a.dim_seq_id = b.dim_seq_id
and a.fleet = b.fleet and a.flight_datetime > sysdate-120 )
from
rdo.rdo_sea_alert_v@evnctpq1 b
/
--
MY question is -- is there an issue in running cursor(Select from remote_table ....)
as even at evnctpq1 -- when I use a local table this query works perfectly..problem comes only when I use a table which is at the remote instance.
I have searched metalinlk but did not get a clear description ...of this.I tried google there someone has asked this question but there is no answer.
any help will be great.
Thanks
Ajeet
October 14, 2004 - 10:24 am UTC
Thanks -- The links were very helpful.
Ajeet, October 16, 2004 - 5:43 am UTC
Tom,
Thanks for the Links -- Solution of the problem was
instead of using a remote table -- use a view for that table. don't know what is the logic.But using the view worked and solve the probelm.
Thanks
Ajeet
8i Documentation
Robert, October 25, 2004 - 5:50 pm UTC
Tom,
Version 8.1.7.4.
Referring to the original question...can you please tell me where in the 8i documentation it says...
1) The 8i pl/sql and sql parsers are different.
2) Native dynamic sql uses the sql parser (vs. the pl/sql parser).
(I have been looking through the Concepts guide, Oracle8i Application Developers Guide - Fundamentals, and PL/SQL Users Guide and Reference)
Thanks,
Robert.
October 25, 2004 - 7:45 pm UTC
it doesn't, most implementation details are not "documented".
however, it is trivial to show empirically that they are -- you have sql that runs OK in sqlplus -- it fails to compile in plsql -- it succeeds if executed via NDS.
there are billions of implementation details that are not documented.
Pretty good inductive reasoning
Robert, October 26, 2004 - 10:32 am UTC
Tom,
Not 100% airtight according to formal deductive logic... but close enough! :)
Thanks for your faithful and valuable service to the Oracle community!
Robert.
Refcursor Example in your Book : Page 33
abhay, November 03, 2004 - 11:48 am UTC
Tom,
I copied the REFCURSOR example in your book (Expert O on O ) on Page 33.
Why do I get error when I try to print second time ?
============
Create table x4
2 as
3* select table_name from user_tables
gname> /
Table created.
gname> variable x refcursor;
gname> begin
2 open :x for select * from x4;
3 end;
4 /
PL/SQL procedure successfully completed.
gname> delete from x4;
17 rows deleted.
gname> commit;
Commit complete.
gname> print :x;
TABLE_NAME
------------------------------
A3
BLK
BLK2
BLK3
EXCL_USER_SAVE
MYTAB
PART_TAB
PLAN_TABLE
SQLTABLE
SQLTABLE2
SQLTABLE3
T
T1
T2
T3
T4
T5
17 rows selected.
gname> PRINT :X;
SP2-0625: Error printing variable "x"
November 04, 2004 - 1:37 am UTC
you already printed X, just as you cannot get blood from a stone, you cannot get more rows from an empty - closed cursor.
Embedded Cursor/ Ref Cursor unable to be cached
Chris Ellis, December 20, 2004 - 6:03 pm UTC
Tom,
Am I right in thinking that the "embedded cursors"/Ref cursors are not going to be cached and hence soft-parsed for each "outer" row. [Based on reading Effective Oracle p297] The tkprof report I have, taken from charly's example above seems to indicate this :-
SELECT "A2"."EMPNO" "EMPNO","A2"."ENAME" "ENAME"
FROM
"EMP" "A2" WHERE "A2"."DEPTNO"=:CV1$
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 4 0.00 0.00 0 0 0 0
Execute 4 0.03 0.04 0 0 0 0
Fetch 18 0.00 0.00 0 25 0 14
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 26 0.03 0.04 0 25 0 14
Misses in library cache during parse: 0
Optimizer goal: CHOOSE
Parsing user id: 59 (recursive depth: 2)
Rows Row Source Operation
------- ---------------------------------------------------
3 TABLE ACCESS FULL EMP (cr=5 r=0 w=0 time=129 us)
I was wondering if this situation is unavoidable in trying to keep it in one sql statement with embedded cursors?
Great site and great books - Can't wait for the new improved one-on-one.
December 20, 2004 - 6:46 pm UTC
Yes, the downside to ref cursors is they are parsed -- we need N cursor handles simultaneously in general (client could decide to process 100 rows at a time, or 1 or 1000)
the ref cursor needs it's own "cursor" basically -- to get a cursor, we have to parse.
dynamic SQL in PRO*C
A reader, January 22, 2005 - 1:00 pm UTC
Hi
I need to use cursor() function and analytic functions in PRO*C, 8.1.7.4. I am not able because I think these types of SQL need to be run as dynamic SQL.
There are four methods to run dynamic SQL in PRO*C, I think I need method 3 or 4 but I am not sure, do you know which method can be used for my purposes?
January 22, 2005 - 4:22 pm UTC
well, there is ansi dynamic sql too -- "method 5" if you will.
you would be looking at "method 3". It is similar to native dynamic sql in plsql, it'll "hide" the query from the pro*c pre-processor.
Cursors in select?
Sree, February 16, 2005 - 1:00 pm UTC
Tom,
From your answers in this thread(at the begining), you said, this is not implemented in
pl/sql yet and they have plans to do so. Can this be done in pl/sql now (atleast in 10G?)
Here is the query..
select deptno, dname, cursor( select ename from emp where emp.deptno = dept.deptno )
from dept
where deptno = 10
Thanks,
February 16, 2005 - 2:40 pm UTC
the original answer says and demonstrated it working in 9i....
Cursor in Select
Sree, February 17, 2005 - 10:15 am UTC
Tom,
It is working as you mentioned before using this small block:
variable x refcursor
set autoprint on
declare
p_deptno number default 10;
begin
open :x for
select deptno,dname,cursor(select empno,ename,sal from emp_sri e where e.deptno=d.deptno)
from dept d
where deptno=p_deptno;
end;
/
PL/SQL procedure successfully completed.
DEPTNO DNAME CURSOR(SELECTEMPNO,E
---------- -------------------- --------------------
10 Accounting CURSOR STATEMENT : 3
CURSOR STATEMENT : 3
EMPNO ENAME SAL
---------- -------------------- ----------
1234 Matt 2500
2345 John 4567
** I do not want to show CUSOR STATEMENT 3
But how do we implement it in a stored procedure and get the ref cursor and
output all those columns? can you show me an example.
Thanks for all your help.
February 17, 2005 - 1:24 pm UTC
the main use of this feature is to return to a client a result set with optional pointers to other result sets that they probably won't ever use
instead of sending back dept JOINed to emp -- to an application that would probably never show the EMP data -- you send back a cursor, a pointer -- in the event they decide to show it.
In plsql to dump the entire result set -- just join. If you truly think for whatever reason you need a cursor in a cursor, plsql makes this happen most naturally like this;
for x in ( .... )
loop
do whatever
for y in ( select .... where ... = x.column )
loop
do whatever
unexpected ora-01008 (8.1.7.4)
Alexey, June 09, 2005 - 1:09 pm UTC
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.
June 09, 2005 - 6:31 pm UTC
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.
Re: unexpected ora-01008 (8.1.7.4)
Alexey, June 10, 2005 - 10:45 am UTC
> what is the purpose of this query really?
There was a complicated query in our application with the "connect_by" subquery. I just cut it down to demonstrate the problem.
BTW, the query just has been rewritten today cause our customers will not work with support and definitely will not apply any patches on their production 8i systems.
We developers are always pay for customers' oddities and oracle's mistakes. :)
But anyway -- thank you for your reply.
PL/SQL refcursor and maximum open cursors
William, August 02, 2005 - 6:48 am UTC
Hi Tom,
I ran into a 'ORA-01000: maximum open cursors exceeded' error while processeing a query that contains several cursors.
What I do is open the main cursor and fetch it into several sys_refcursors (r_%) and process the sys_refcursors :
open c;
loop
begin
fetch c into l_barcode
, r_author
, r_corp_author
, l_illustration
;
-- Fetching all author attributes
loop
fetch r_author into l_cap
, l_addpre
, l_fname
, l_prefix
;
exit when r_author%notfound;
--
end loop;
..
..
end;
end loop;
close c;
As I said, I ran into ORA-01000, because every sys_refcursor is implicitly opened, but not closed for each record in cursor c. That means, not that I am aware of.
Is there a way to manage this process (besides altering the open_cursors parameter to a value of 1000000)
Kind regards,
William
August 02, 2005 - 8:06 am UTC
no, not "every", just the ones you've fetched.
are you closing them? I've 48,106 rows in my all_objects, insufficient open cursors to have them ALL open at the same time, but yet:
ops$tkyte@ORA10G> show parameter open_cursors
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
open_cursors integer 300
ops$tkyte@ORA10G>
ops$tkyte@ORA10G>
ops$tkyte@ORA10G> declare
2 cursor c is select owner, cursor(select * from dual) c1, cursor(select user_id from all_users where all_users.username =
3 all_objects.owner) c2 from all_objects;
4
5 l_owner all_objects.owner%type;
6 l_c1 sys_refcursor;
7 l_c2 sys_refcursor;
8
9 l_dummy dual.dummy%type;
10 l_user_id all_users.user_id%type;
11
12 l_cnt number := 0;
13 begin
14 open c;
15 loop
16 fetch c into l_owner, l_c1, l_c2;
17 l_cnt := l_cnt+1;
18 dbms_application_info.set_client_info(l_cnt);
19 exit when c%notfound;
20 loop
21 fetch l_c2 into l_user_id;
22 exit when l_c2%notfound;
23 end loop;
24 close l_c2;
25 loop
26 fetch l_c1 into l_dummy;
27 exit when l_c1%notfound;
28 end loop;
29 close l_c1;
30 end loop;
31 close c;
32 end;
33 /
PL/SQL procedure successfully completed.
Same in 9i (with 100 open cursors)...
Result sets in Pro*C?
David Weigel, August 02, 2005 - 11:18 am UTC
Thanks for the Java example, but may I have a brief example of handling a result set from a PL/SQL procedure from C?
August 02, 2005 - 1:55 pm UTC
Re: PL/SQL refcursor and maximum open cursors
William, August 09, 2005 - 9:32 am UTC
I tried implementing the close statement for the cursor, but ended up in an error ORA-01001: invalid cursor
I found out that the only way to close the cursors is to loop through the cursors, with the last opened cursor at the first entry, so f.e. your code is like this:
fetching c into l_c1, l_c2
looping through l_c2, close l_c2
looping through l_c1, close l_c1
If you process like the following, the error is returned:
fetching c into l_c1, l_c2
looping through l_c1, close l_c1
looping through l_c2, close l_c2
Come to think to it, it seems reasonable, or not?
August 09, 2005 - 10:41 am UTC
I'm not sure it is reasonable. I'll file a bug and see what they say. If you take my code and process the columns backwards from the way I did, I get it too (the ora-1001), it should not matter in my mind.
maximum open cursors execeeded
mani, September 01, 2005 - 10:12 am UTC
Hi Tom
The below query fails with maximum open cursors exceeded. How to tune the query to overcome the cursor exceeded
GO_BLOCK('CB_ERROR_DETAILS');
FIRST_RECORD;
FOR I IN (SELECT ORL.FILE_TRANSFER_ID FILE_TRANSFER_ID,
OML.BRANCH_CODE BRANCH_CODE,
OML.DATE_TIME_SENT DATE_TIME_SENT,
ORL.ERROR_TYPE ERROR_TYPE,
OML.FILE_NAME FILE_NAME,
TRUNC(OML.LOG_DATE) LOG_DATE,
ORL.LINE_NUMBER LINE_NUMBER,
ORL.ERROR_MESG ERROR_MESG,
ORL.ERROR_CODE ERROR_CODE,-- ** Added By Mithna **
ORL.CLEARED_IND,
ORL.ROWID IDROW
FROM OD_REJECTION_LOG ORL,
OD_MAIL_LOG OML
WHERE OML.FILE_TRANSFER_ID = ORL.FILE_TRANSFER_ID
AND OML.BRANCH_CODE = NVL(:CB_FILTER.DI_V_BRANCH_CODE,OML.BRANCH_CODE)
AND TRUNC(OML.LOG_DATE) BETWEEN TRUNC(NVL(:CB_FILTER.TI_D_DATE_FROM,log_date))
AND TRUNC(NVL(:CB_FILTER.TI_D_DATE_TO,log_date))
AND SUBSTR(OML.FILE_NAME,1,1) = DECODE(:CB_FILTER.TI_V_FILE_TYPE,'F', SUBSTR(OML.FILE_NAME,1,1),:CB_FILTER.TI_V_FILE_TYPE)
AND OML.FILE_NAME = NVL(:CB_FILTER.TI_V_FILE_NAME,OML.FILE_NAME)
AND ((:CB_FILTER.RG_ERROR_STATUS != 'A' AND NVL(CLEARED_IND,'N') = :CB_FILTER.RG_ERROR_STATUS
)
OR
(:CB_FILTER.RG_ERROR_STATUS = 'A' AND NVL(CLEARED_IND ,'~') = NVL(CLEARED_IND ,'~')
)
)
--ORDER BY 4)
ORDER BY 6 DESC,5 ASC)
September 01, 2005 - 3:45 pm UTC
sorry, if that query is doing it , it simply means you have open cursors set too low -- i see only one cursor there.
maximum open cursors execeeded
mani, September 02, 2005 - 1:08 am UTC
I had set open_cursors = 1000
September 02, 2005 - 1:29 am UTC
so? (just means maybe you exceeded that and nothing is wrong on Oracle's part, but rather you have lots of cursors open)
tell you what, run it with sql_trace and see what is happening, you'll see your cursors, our cursors, all cursors in there.
Cursor expression in 9i
Dipti, September 21, 2005 - 4:37 pm UTC
in the first question you said
ORA-00600: internal error code, arguments: [kokbnp2], [942], [], [], [], [],
[], []
occurrs in the oracle 8i and prior version.
I am using oracle 9i and I am still getting same error?
Please help?
September 21, 2005 - 8:10 pm UTC
support, ora-600 = contact support.
Question in Ref Cursor in Oracle
Oracle Knowledge Seeker, September 22, 2005 - 4:17 am UTC
Can I get all the results that I have got in a ref Cursor into a variable instead of iterating through the cursor
For ex :
I declare a cursor as
TYPE dep_curtype IS REF CURSOR;
dep_id_cur_var dep_curtype ;
OPEN dep_id_cur_var FOR SELECT dep_id FROM JOB_DEP;
Now I want to get all the values that is fetched in dep_id_cur_var into a variable
For ex : If the values fetched from the Query SELECT dep_id FROM JOB_DEP; is 1,2,3,4,5
September 22, 2005 - 1:52 pm UTC
no, you would have to write a query that returned a single row with the values concatenated in order to do that - search this site for stragg for example.
but you can select all of the values into an ARRAY
fetch cursor_variable BULK COLLECT into l_data;
Ref Cursor
A reader, September 22, 2005 - 4:29 am UTC
Can I get all the results that I have got in a ref Cursor into a variable instead of iterating through the cursor
For ex :
I declare a cursor as
TYPE dep_curtype IS REF CURSOR;
dep_id_cur_var dep_curtype ;
OPEN dep_id_cur_var FOR SELECT dep_id FROM JOB_DEP;
Now I want to get all the values that is fetched in dep_id_cur_var into a variable at once without iterating through the cursor
For ex : If the values fetched from the Query SELECT dep_id FROM JOB_DEP; is 1,2,3,4,5
some more help.
Vijay, November 25, 2005 - 5:54 am UTC
Hi Tom,
good day to you, with respect to cursor expression can this be used to form a query which returns me all the tables in a schema with a particualr column name and the table having a givn value in that column, say col1 in tables A1, A2, A3 having value 'test', so only these three tables are selected by the query.
As always thanks a lot for all your help.
Kind Regards,
Vijay.
November 25, 2005 - 10:50 am UTC
you have to build a query that would explicitly reference the tables you want to reference (no)
some more light on this please
Vijay, November 28, 2005 - 5:58 am UTC
Hi Tom,
good day to you, with reference to above post do you mean it's not possible by a query and will require dynamic query processing please if you can shed some more light on this.
Kind Regards,
Vijay
November 28, 2005 - 7:43 am UTC
you will need to have a query that explicitly references the tables in question. If you cannot do that with a static query - because the list of tables is not known at compile time - they dynamic sql will be your only choice.
ORA-00600: internal error code, arguments: [kokbcrwo1], [1], [2], [], [], [],
Sameer Babu, December 05, 2005 - 10:36 am UTC
I am getting the following error when I use the DISTINCT clause in the query which contains CURSOR expression:
ERROR at line 1:
ORA-00600: internal error code, arguments: [kokbcrwo1], [1], [2], [], [], [],
[], []
Query was:
SELECT DISTINCT a.commandTableName, CURSOR(SELECT d.tableColumnName, d.defaultValue FROM CommandColumns d WHERE d.commandId = a.commandId) FROM CommandConfig a, tCommands b, tConfig c WHERE a.commandId = b.commandId AND b.tId = c.tId AND c.eVersion = 13 AND c.tVersion = 13 AND a.isIdName IS NULL AND UPPER(c.internalName) IN (UPPER('test'))
December 06, 2005 - 5:05 am UTC
and ora-600 means.....
[tkyte@localhost ~]$ oerr ora 600
00600, 00000, "internal error code, arguments: [%s], [%s], [%s], [%s], [%s], [%s], [%s], [%s]"
// *Cause: This is the generic internal error number for Oracle program
// exceptions. This indicates that a process has encountered an
// exceptional condition.
// *Action: Report as a bug - the first argument is the internal error number
[tkyte@localhost ~]$
contact support.
but they will say "thanks for pointing out that we are not raising the right error message - distinct on a cursor doesn't make sense"
(meaning, the bug is the wrong error is being reported, not that distinct is broken in this case)
In the meantime
Bob B, December 06, 2005 - 9:14 am UTC
In the meantime, if you weren't looking for distinct cursors (whatever that would mean), just use group by.
December 06, 2005 - 9:48 am UTC
how do you group by a cursor?
REF Cursor
Marc, January 10, 2006 - 10:21 am UTC
is it possible that the refcursor uses an defined sql_type or record as an output parameter.
I need a special name for the variables in the output from the select query that uses the refcursor?
I tried with the following piece of code:
I created a package were the type is defined
create or replace package types as
TYPE my_order_rec is record
( p_order_id_pk number,
p_order_id_fk number,
p_bill_id_pk number,
p_bill_no varchar2(10));
TYPE order_cur IS REF CURSOR RETURN my_order_rec;
END Types;
so I have problems with the procedure
create or replace procedure current_customers
(
p_order_id_pk in orders.order_id_pk%TYPE,
order_cur out types.my_order_rec
)
OPEN order_cur FOR select o.order_id_pk, c.bill_id_fk,
c.bill_id_pk, c.bill_no
from orders o,
bill c
where o.order_id_pk = c.bill_id_pk
and o.order_id_pk = p_order_id_pk;
END;
/
it does not work as it should,i hope you can give me a tipp
thanks
January 10, 2006 - 11:00 am UTC
you used the wrong type for order_cur, you were missing "as" and "begin"
ops$tkyte@ORA9IR2> create or replace procedure current_customers
2 (
3 p_order_id_pk in orders.order_id_pk%TYPE,
4 order_cur out types.order_cur
5 )
6 as
7 begin
8
9 OPEN order_cur FOR select o.order_id_pk, c.bill_id_fk,
10 c.bill_id_pk, c.bill_no
11 from orders o,
12 bill c
13 where o.order_id_pk = c.bill_id_pk
14 and o.order_id_pk = p_order_id_pk;
15
16 END;
17 /
Procedure created.
Thanks Tom
Jose, January 19, 2006 - 11:42 am UTC
Incorrect result from ref cursor
Branka, March 14, 2006 - 2:08 pm UTC
Tom,
I can not find where am I making mistake. Can you please help me.
I created sample code:
CREATE TABLE B_TEST (ID NUMBER, TEKST VARCHAR2(100 byte))
CREATE TABLE bB_TEST (ID NUMBER, TEKST VARCHAR2(100 byte))
insert into b_test VALUES(1,'A1');
insert into b_test VALUES(1,'A1');
insert into b_test VALUES(1,'A3');
insert into b_test VALUES(2,'B1');
insert into b_test VALUES(2,'B3');
insert into b_test VALUES(3,'C1');
insert into b_test VALUES(3,'C2');
insert into b_test VALUES(3,'C3');
insert into bB_test VALUES (1,'A1');
insert into bB_test VALUES(1,'A1');
insert into bB_test VALUES(1,'A2');
insert into bB_test VALUES(2,'B1');
insert into bB_test VALUES(2,'B2');
insert into bB_test VALUES(3,'C2');
insert into bB_test VALUES(3,'C3');
select * from b_test
minus
select * from bb_test
ID TEKST
--------- ------------------
1 A3
2 B3
3 C1
CREATE OR REPLACE PACKAGE COMPARE_CDS_AND_CDSP
as
TYPE refcursor_report IS REF CURSOR;
procedure compare_mpc_ipc(refcur_mpcipc OUT refcursor_report);
end;
CREATE OR REPLACE PACKAGE BODY COMPARE_CDS_AND_CDSP AS
PROCEDURE compare_mpc_ipc (refcur_mpcipc OUT refcursor_report)
AS
TYPE mpcipc_rec_type IS RECORD (
id number,
tekst VARCHAR2(100) ,
description varchar2(200));
mpcipc_report mpcipc_rec_type;
BEGIN
OPEN refcur_mpcipc FOR
SELECT id,tekst,'test'
FROM b_test
minus
SELECT id,tekst,'test'
FROM bb_test;
FETCH refcur_mpcipc INTO mpcipc_report;
-- WHILE refcur_mpcipc%FOUND LOOP
-- DBMS_OUTPUT.PUT_LINE(mpcipc_report.id||' '||mpcipc_report.tekst||' '||mpcipc_report.DESCRIPTION);
-- FETCH refcur_mpcipc INTO mpcipc_report;
END LOOP;
END compare_mpc_ipc;
END;
If I run exec COMPARE_CDS_AND_CDSP.compare_mpc_ipc(:B)
branka_dba@DIESEL1_CDS>print b
ID TEKST 'TES
---------- ---------- ----
2 B3 test
3 C1 test
If I remove coments from the SP, and print records, I will get
branka_dba@DIESEL1_CDS>exec COMPARE_CDS_AND_CDSP.compare_mpc_ipc(:B)
1 A3 test
2 B3 test
3 C1 test
I would like to use ref cursor as out variable, but with correct result.
Thanks
Branka
March 15, 2006 - 9:24 am UTC
why are you fetching from it? once you fetch a row from that ref cursor - no one else will!
just open it, don't fetch it.
Find problem
Branka, March 14, 2006 - 2:14 pm UTC
I didn't comment
FETCH refcur_mpcipc INTO mpcipc_report
Thanks
ref cursor
Branka, March 14, 2006 - 2:57 pm UTC
I have one mor question, with almost same example.
Package body is a litle bit different.
I would like autput for all records that I find, but with this SP I will get only one (last one)
I know that I can create temporary table, but I would like to know if it is some other solution.
Thanks a lot.
Branka
CREATE OR REPLACE PACKAGE BODY COMPARE_CDS_AND_CDSP AS
PROCEDURE compare_mpc_ipc (refcur_mpcipc OUT refcursor_report)
AS
BEGIN
FOR x IN ( SELECT id, count(*) ptnt_count
FROM b_test
GROUP BY id
MINUS
SELECT id, count(*) ptnt_count
FROM bb_test
GROUP BY id
)
LOOP
BEGIN
OPEN refcur_mpcipc FOR
SELECT id,tekst,'test'
FROM b_test
where id=x.id
minus
SELECT id,tekst,'test'
FROM bb_test
where id=x.id;
END;
END LOOP;
END compare_mpc_ipc;
END;
March 15, 2006 - 9:46 am UTC
explain in english what your "goal" is - not the code, phrase in text your question, from that we'll derive a query.
seems like:
with data as
( SELECT id, count(*) ptnt_count
FROM b_test
GROUP BY id
MINUS
SELECT id, count(*) ptnt_count
FROM bb_test
GROUP BY id)
select id, tekst, 'test'
from b_test where id in (select id from data)
MINUS
select id, tekst, 'test'
from bb_test
where id in (select id from data);
ref cursor
Branka, March 15, 2006 - 10:31 am UTC
I would like to compare id number of records for each id is same in 2 tables. If it is not same, than I would like more information about that record where number is different.
Thanks
Branka
March 15, 2006 - 5:21 pm UTC
er?
Invalid cursor error calling SP via dblink
Chris, April 04, 2006 - 9:01 am UTC
Tom, there were some references above to invalid cursor's but I don't think it is the same scenario I have. I'm running two databases, both 9.2.0.7. I'm trying to call a packaged procedure in one database from the other that has a ref cursor as a parameter. Calling code looks like the following:
declare
c gui.t_cursor@rem_db;
v_column varchar2(100);
begin
gui.getcolumn@rem_db(c);
loop
fetch c into v_column;
exit when c%NOTFOUND;
dbms_output.put_line(v_column);
end loop;
end;
/
When I run this code I get ORA-01007: variable not in select list. Repeated executions then yield ORA-01001: invalid cursor (maybe because the cursor is open?).
However, if i remove the database links from the code and run it on the remote database as a local PL/SQL block, all works just fine.
Any suggestions?
April 04, 2006 - 10:00 am UTC
ref cursors are not supported over dblinks at all.
PL/SQL Procedure returning a Ref-Cursor with "embedded Cursors
Venkat, May 18, 2006 - 3:58 am UTC
Hi Tom,
I ran your example , when I ran as listed below it ran fine .
SQL> declare
2 cursor c is select owner, cursor(select * from dual) c1,
3 cursor(select user_id from all_users where all_users.username =
4 all_objects.owner) c2 from all_objects;
5
6 l_owner all_objects.owner%type;
7 l_c1 sys_refcursor;
8 l_c2 sys_refcursor;
9
10 l_dummy dual.dummy%type;
11 l_user_id all_users.user_id%type;
12
13 l_cnt number := 0;
14 begin
15 open c;
16 loop
17 fetch c into l_owner, l_c1,l_c2 ;
18 l_cnt := l_cnt+1;
19 dbms_application_info.set_client_info(l_cnt);
20 exit when c%notfound;
21 loop
22 fetch l_c2 into l_user_id;
23 exit when l_c2%notfound;
24 end loop;
25 close l_c2;
26
27 loop
28 fetch l_c1 into l_dummy;
29 exit when l_c1%notfound;
30 end loop;
31 close l_c1;
32
33
34 end loop;
35 close c;
36 end;
37 /
PL/SQL procedure successfully completed.
But if I swap the variables in the fetch , it gives me the error as shown below
SQL> declare
2 cursor c is select owner, cursor(select * from dual) c1,
3 cursor(select user_id from all_users where all_users.username =
4 all_objects.owner) c2 from all_objects;
5
6 l_owner all_objects.owner%type;
7 l_c1 sys_refcursor;
8 l_c2 sys_refcursor;
9
10 l_dummy dual.dummy%type;
11 l_user_id all_users.user_id%type;
12
13 l_cnt number := 0;
14 begin
15 open c;
16 loop
17 fetch c into l_owner, l_c2,l_c1 ;
18 l_cnt := l_cnt+1;
19 dbms_application_info.set_client_info(l_cnt);
20 exit when c%notfound;
21 loop
22 fetch l_c2 into l_user_id;
23 exit when l_c2%notfound;
24 end loop;
25 close l_c2;
26
27 loop
28 fetch l_c1 into l_dummy;
29 exit when l_c1%notfound;
30 end loop;
31 close l_c1;
32
33
34 end loop;
35 close c;
36 end;
37 /
declare
*
ERROR at line 1:
ORA-01722: invalid number
ORA-06512: at line 22
Is this a bug or am I doing something wrong here. I'm using Oracle 9i r2 on Windows
May 19, 2006 - 9:07 am UTC
l_cs points to (select * from dual)
select * from dual returns "not a number"
I don't know why you think the select * from dual would be appropriate to fetch into a number type?
PL/SQL Procedure returning a Ref-Cursor with "embedded Cursors
Venkat, May 22, 2006 - 4:16 am UTC
Thanks Tom, I understand that select * from dual does not return a number , but inside the loop when your a fetching values from cursor c
fetch c into l_c1,l_c2 ,(AS BOTH ARE REF_CURSORS) how does it matter if I fetch l_c1 or l_c2 in the same order in which it has been specified in the cursor statement , i.e.
cursor as select col1, cursor(select * from dual) c1,
cursor(select colname2 from table2) c2
what if I do
open c;
fetch c into ref_cursor_for_c2,ref_cursor_for_c1
Is my understanding wrong!
Please explain
Venkat
May 22, 2006 - 7:55 am UTC
22 fetch l_c2 into l_user_id;
that is the LINE OF CODE that is failing, l_c2 contains a ref cursor that is pointing to "select * from dual", fetching DUAL.DUMMY which contains the letter "X" into l_user_id which is a NUMBER - well, that just doesn't work.
Forget the ref cursors, they are not the "problem" here, the problem is you fetching the string "X" into the variable l_user_id which is a NUMBER and hence cannot hold the letter "X"
Passing VARCHAR2( as a set of numbers) for WHERE ... IN Condition
Ranjan Srivastava, May 28, 2006 - 2:54 pm UTC
Hi tom,
-- Scott/tiger, Table : EMP
-- Stored Procedure
CREATE OR REPLACE PROCEDURE EMP_COUNT (empNoList IN VARCHAR2, emp_list_cur OUT SYS_REFCURSOR)
AS
BEGIN
dbms_output.put_line(empNoList);
OPEN emp_list_cur FOR SELECT ename FROM Emp
WHERE EMP.EMPNO IN (empNoList) ;
END ;
/
--
DECLARE
v sys_refcursor;
a varchar2(9);
ename varchar2(20);
BEGIN
a:='7782,7788';
emp_count(a,v);
LOOP
FETCH v into ename;
EXIT when v%notfound;
dbms_output.put_line(ename);
END LOOP;
END;
When I run this code, the query in SP does not accept the set of numbers. If I type out the number in the IN part (like EMP.EMPNO IN (7782,7788)), then I get the result.
How to pass the string to the IN part?
Regards
May 28, 2006 - 6:27 pm UTC
Very useful feature, but need some more help on this.
Vijay Sehgal, September 25, 2006 - 6:34 am UTC
Dear Tom,
good day to you as always, I need your help on this.
The structures for requirement we have are as follows.
user_master
user_id(pk)
login_id
username
ugroup_id (fk to user_group.group_id)
user_group
ugroup_id (pk)
group_name
role_id (fk to role_id of roles_master.role_id)
roles_master
role_id(pk)
role_name
role_status
security_master
security_id(pk)
role_id(fk to roles_master.role_id)
use_case_id (fk to use_case.use_case_id)
use_case
use_case_id(pk)
use_case_name
use_case_action
portfolio_master
portfolio_id
portfolio_name
portfolio_group_id
portfolio_group
portfolio_group_id
group_name
access_mode
access_id
access_mode
portfoliogroup_user_mapping
id
portfolio_group_id(fk to portlio_master.portfolio_id)
user_id(fk to user_master.user_id)
access_id (fk to access_mode.access_id)
portfoliogroup_user_group_map
id
ugroup_id(fk to user_group.ugroup_id)
portfolio_group_id(fk to portfolio_group.portfolio_group_id)
access_id (fk to access_mode.access_id)
We need to fetch the result as follows
user_id,ugroup_id,role_id,use_case_name,use_case_action,portfolio_group_
id (direct access via portfoliogroup_user_mapping), access_id (on the portfolio_group direct access via portfoliogroup_user_mapping), portfolio_group_id(access via portfoliogroup_user_group_map), access_id (on the portfolio_group access via portfoliogroup_user_group_map ), portfolios(access to all portfolios access via portfoliogroup_user_mapping and portfoliogroup_user_group_map)
I hope I was able to make my point clear to you, so going forward this can be done by breaking the requirement into multiple queries and returning the data to java via refcursor and or object types other way is via the CURSOR FUNCTION as you have mentioned in this thread.
I would like to have your advise on this, which mechanism will be better in long run.
your help in this regard is much appreciated as always.
Kind Regards,
Vijay Sehgal
September 25, 2006 - 2:53 pm UTC
not really clear.
You can
a) just join, joins work pretty good.
b) use the CURSOR() construct if it makes sense for you to do so
Returning the Result of a Select in a Procedure
Avishay, November 19, 2006 - 9:44 am UTC
Hi Tom,
I'm trying to return the result of a select statment in a procedure.
I know I'm missing something here.
I tried to use a ref cursor but it keeps failing.
here is an example of the procedure:
create or replace procedure test1 ( x_1 in number,x_2 in number, ->What_goes_here out ) is
begin
select acc.acc_num
acc.name,
acc.phone_no,
acc.is_avail,
acc.approved
from accounts acc
where acc.area= x_1
and acc.acc_branch = x_2;
-- Need to return the result of this query
end ;
which cursor should I? use and how?
I know this basic, but what ever I tries I'm doing something wrong here.
Sorry for not providing a more detailed testcase. I'm not a my computer right now.
Avishay
November 20, 2006 - 2:46 am UTC
if you were not at a computer.....
how did you submit this??????
but you are right, this is pretty basic, it is well covered in the documentation for example, heavily and well covered.
but here is an example:
</code>
http://asktom.oracle.com/~tkyte/ResultSets/index.html <code>
you need a computer to see it though :)
Thanks
Avishay, November 21, 2006 - 2:24 am UTC
Hi Tom,
Thanks, that helped.
I meant to say that I wasn't at MY computer. :)
I guess I'll survive the banter :)
Problems with error ORA-1722
Tomas Gonzalez, February 12, 2007 - 10:43 am UTC
Hi Tom,
I'm working with JAVA and PL/SQL. I have installed JDK 1.4_10 and ORACLE DB is 9i.
When i invoke the procedure, in any machine, this work correctly, but in othres fail wiht error ORA-1722.
PROCEDURE RPT_TIEMPOS_LLAMADAS_PLAT
(
idSupervisor IN VARCHAR2,
idSite IN VARCHAR2,
fechaInicio IN VARCHAR2, /* fecha de inicio de la consulta formato yyyymmdd */
fechaFinConsulta IN VARCHAR2,
RETORNO OUT INTEGER,
DESCRIPCION_ERROR OUT VARCHAR2,
CURSOR_CONSULTA OUT tcursor
) AS /* Resumen Hold transf lib abn hol */
qrySql VARCHAR2(10000);
BEGIN
/* Validación de parámetros obligatorios*/
RETORNO := 0;
DESCRIPCION_ERROR := 'NO HAY ERROR';
IF (fechaInicio ='0') THEN
RETORNO := 1;
DESCRIPCION_ERROR := 'Falta parámetro FECHA_INICIO CONSULTA';
RETURN;
END IF;
IF (fechaFinConsulta='0') THEN
RETORNO := 2;
DESCRIPCION_ERROR := 'Falta parámetro FECHA_HASTA CONSULTA';
RETURN;
END IF;
qrySql := 'SELECT PLAT.NOMBRE_PLAT, ' ||
' SUM(NVL(INDEAC.LLAM_ATEN, 0)) suma_LLAM_ATEN,' ||
' SUM(NVL(INDEAC.LLAM_TRANSF, 0)) suma_LLAM_TRANSF, ' ||
' SUM(NVL(INDEAC.SEG_ACD, 0)) suma_SEG_ACD, ' ||
' SUM(NVL(INDEAC.SEG_HOLD, 0)) suma_SEG_HOLD,' ||
' SUM(NVL(INDEAC.SEG_ENTRADA, 0)) suma_SEG_ENTRADA, ' ||
' SUM(NVL(INDEAC.SE_OUT, 0)) suma_SE_OUT, ' ||
' SUM(NVL(INDEAC.SEG_ACW_CC, 0)) suma_SEG_ACW_CC, ' ||
' SUM(NVL(INDEAC.SEG_ACW_SC, 0)) suma_SEG_ACW_SC, ' ||
' SUM(NVL(INDEAC.LLAM_LIB, 0)) suma_LLAM_LIB, ' ||
' SUM(INDEAC.LLAM_ABN_EN_HOLD) suma_LLAM_ABN_EN_HOLD, ' ||
' ROUND(DECODE(SUM(NVL(INDEAC.LLAM_ATEN, 0)), 0, 0, SUM(NVL(INDEAC.LLAM_TRANSF, 0)) / SUM(NVL(INDEAC.LLAM_ATEN, 0))) * 100, 2) suma_PORC_LLAM_TRANSF, ' ||
' ROUND(DECODE(SUM(NVL(INDEAC.SEG_ACD, 0) + NVL(INDEAC.SEG_HOLD, 0) + NVL(INDEAC.SEG_ENTRADA, 0) + NVL(INDEAC.SE_OUT, 0) + NVL(INDEAC.SEG_ACW_CC, 0)), 0, 0, SUM(NVL(INDEAC.SEG_HOLD, 0)) / SUM(NVL(INDEAC.SEG_ACD, 0) + NVL(INDEAC.SEG_HOLD, 0) + NVL(INDEAC.SEG_ENTRADA, 0) + NVL(INDEAC.SE_OUT, 0) + NVL(INDEAC.SEG_ACW_CC, 0))) * 100, 2) PORC_HOLD_SOBRE_TMO, '||
' ROUND(DECODE(SUM(NVL(INDEAC.LLAM_ATEN, 0)), 0, 0, SUM(NVL(INDEAC.LLAM_LIB, 0)) / SUM(NVL(INDEAC.LLAM_ATEN, 0))) *100, 2) suma_PORC_LLAM_LIB, ' ||
' ROUND(DECODE(SUM(NVL(INDEAC.LLAM_ATEN, 0)), 0, 0, SUM(NVL(INDEAC.LLAM_ABN_EN_HOLD, 0))/SUM(NVL(INDEAC.LLAM_ATEN, 0))) * 100, 2) suma_PORC_LLAM_ABN_HOLD ' ||
' FROM T_CC_PLATAFORMA plat, ' ||
' T_CC_SUPERVISOR sup, ' ||
' T_CC_SUPERVISOR_EJECUTIVO supeac, ' ||
' T_CC_INDICES_EJECUTIVO indeac, ' ||
' T_CC_EJECUTIVO_EAC ejec ' ||
'WHERE ejec.LOGIN_EAC IS NOT NULL ';
IF idSupervisor <> '0' THEN
qrySql := qrySql || 'AND sup.ID_SUPERVISOR =''' || idSupervisor || '''';
END IF;
IF idSite <> '0' THEN
qrySql := qrySql || ' AND indeac.ID_SITE = ''' || idSite || '''';
END IF;
qrySql := qrySql || ' AND indeac.LOGIN_EAC = ejec.LOGIN_EAC ' ||
' AND sup.ID_SUPERVISOR = supeac.ID_SUPERVISOR ' ||
' AND ejec.RUT = supeac.RUT ' ||
' AND ejec.Dv = supeac.Dv ' ||
' AND indeac.ID_PLATAFORMA = plat.ID_PLATAFORMA';
qrySql := qrySql || ' AND TRUNC(INDEAC.FECHA) BETWEEN TO_DATE(''' || fechaInicio || ''', ''YYYYMMDD'') AND TO_DATE(''' || fechaFinConsulta || ''', ''YYYYMMDD'')';
qrySql := qrySql || ' GROUP BY plat.NOMBRE_PLAT';
DESCRIPCION_ERROR := qrySql;
OPEN CURSOR_CONSULTA FOR qrySql;
EXCEPTION
WHEN OTHERS THEN
RETORNO := SQLCODE;
DESCRIPCION_ERROR := SQLERRM;
END;
In J2EE is invoke of this way:
CallableStatement stmt = con
.prepareCall("{ call Pkg_Reportes_Call_Center.RPT_TIEMPOS_LLAMADAS_PLAT (?,?,?,?,?,?,?) }");
stmt.setString(1, idSupervisor);
stmt.setString(2, idSite);
stmt.setString(3, fechaInicio);
stmt.setString(4, fechaFinConsulta);
stmt.registerOutParameter(5, OracleTypes.INTEGER);
stmt.registerOutParameter(6, OracleTypes.VARCHAR);
stmt.registerOutParameter(7, OracleTypes.CURSOR);
stmt.execute();
if ("0".equals(stmt.getString(5))) {
rs = (ResultSet) stmt.getObject(7);
And in the run-time fail with a exception SQL java.sql.SQLException: ORA-01722
This is only machine. ¿Why? Please, your help whith this problem.
Is a web apliccation with tomcat 5.0.28
Regards,
Tomas from Santiago of Chile
February 12, 2007 - 11:39 am UTC
are you using strings to store numbers.
are you implicitly converting strings to numbers.
The maximum number of arguments in a CASE expression is 127
vithal, June 20, 2007 - 10:00 am UTC
Hi,
the following case stament is working in 9i where number of arguments in a CASE expression are 148 but the same is not working in oracle 10g.
Can you please suggest, is this a bug in 10g?
create table emp(no number)
select case
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
when no = 1 then 1
end from emp
June 20, 2007 - 11:21 am UTC
http://docs.oracle.com/docs/cd/B19306_01/server.102/b14200/expressions004.htm#i1033392 ...
The maximum number of arguments in a CASE expression is 255. All expressions count toward this limit, including the initial expression of a simple CASE expression and the optional ELSE expression.
Each WHEN ... THEN pair counts as two arguments. To avoid exceeding this limit, you can nest CASE expressions so that the return_expr itself is a CASE expression.
....
case
A reader, June 20, 2007 - 12:41 pm UTC
Tom,
that's fine the same was present in 9i docs. but the sql query which i have sent you is working fine in 9i...
Why this is not working in 10g?
June 20, 2007 - 1:29 pm UTC
they fixed something that wasn't working properly in the earlier release. You are pointing at the wrong version technically here - it was a bug that it worked before.
Case expression
A reader, June 21, 2007 - 2:22 am UTC
Tom,
That¿s perfectly fine, but now the issue is while database upgrade, we have to change lots of code just because of this fix.
I am planning to raise the TAR/SR to oracle to get this fix.
Can you please suggest, is this correct?
Many Thanks,
Vithal
June 21, 2007 - 10:26 am UTC
they will tell you simply "it is working as documented", sorry - don't know what else to tell you.
out of scope
dxl, December 05, 2008 - 2:04 pm UTC
i have a question about the test case below...my second embedded cursor select won't run because the column that is joined on cannot be seen by the outer select statement.
How can i get around this?
set lines 200
set pages 2000
variable p_start_date varchar2(10)
variable p_end_date varchar2(10)
exec :p_start_date := '04/12/2008';
exec :p_end_date := '14/12/2008';
create table t1 ( c1 date );
insert into t1 values (TRUNC(SYSDATE-1));
insert into t1 values (TRUNC(SYSDATE-2));
insert into t1 values (TRUNC(SYSDATE-3));
insert into t1 values (TRUNC(SYSDATE-4));
insert into t1 values (TRUNC(SYSDATE-5));
insert into t1 values (TRUNC(SYSDATE-6));
select * from t1;
select dummy_date,
CURSOR(
select c1
from t1
where t1.c1 = d.dummy_date
) as inner_cursor
FROM (
SELECT CAST( TRUNC(( TO_DATE(:p_start_date, 'DD/MM/YYYY') ) + (ROWNUM) - 1) AS DATE) as dummy_date
FROM all_tab_columns
WHERE ROWNUM <= ( (( TO_DATE(:p_end_date, 'DD/MM/YYYY') - ( TO_DATE(:p_start_date, 'DD/MM/YYYY') )) + 1) * 1 )
) d;
---------------
-- The results i get are:
C1
-------------------
04/12/2008 00:00:00
03/12/2008 00:00:00
02/12/2008 00:00:00
01/12/2008 00:00:00
30/11/2008 00:00:00
29/11/2008 00:00:00
6 rows selected.
DUMMY_DATE INNER_CURSOR
------------------- --------------------
04/12/2008 00:00:00 CURSOR STATEMENT : 2
CURSOR STATEMENT : 2
C1
-------------------
04/12/2008 00:00:00
05/12/2008 00:00:00 CURSOR STATEMENT : 2
CURSOR STATEMENT : 2
no rows selected
DUMMY_DATE INNER_CURSOR
------------------- --------------------
06/12/2008 00:00:00 CURSOR STATEMENT : 2
CURSOR STATEMENT : 2
no rows selected
DUMMY_DATE INNER_CURSOR
------------------- --------------------
07/12/2008 00:00:00 CURSOR STATEMENT : 2
CURSOR STATEMENT : 2
no rows selected
DUMMY_DATE INNER_CURSOR
------------------- --------------------
08/12/2008 00:00:00 CURSOR STATEMENT : 2
CURSOR STATEMENT : 2
no rows selected
DUMMY_DATE INNER_CURSOR
------------------- --------------------
09/12/2008 00:00:00 CURSOR STATEMENT : 2
CURSOR STATEMENT : 2
no rows selected
DUMMY_DATE INNER_CURSOR
------------------- --------------------
10/12/2008 00:00:00 CURSOR STATEMENT : 2
CURSOR STATEMENT : 2
no rows selected
DUMMY_DATE INNER_CURSOR
------------------- --------------------
11/12/2008 00:00:00 CURSOR STATEMENT : 2
CURSOR STATEMENT : 2
no rows selected
DUMMY_DATE INNER_CURSOR
------------------- --------------------
12/12/2008 00:00:00 CURSOR STATEMENT : 2
CURSOR STATEMENT : 2
no rows selected
DUMMY_DATE INNER_CURSOR
------------------- --------------------
13/12/2008 00:00:00 CURSOR STATEMENT : 2
CURSOR STATEMENT : 2
no rows selected
DUMMY_DATE INNER_CURSOR
------------------- --------------------
14/12/2008 00:00:00 CURSOR STATEMENT : 2
CURSOR STATEMENT : 2
no rows selected
11 rows selected.
-- Now using this sql and restricting the inner selects using a rownum doesn't run:
select dummy_date,
CURSOR(
select c1
from (
select c1
from t1
where t1.c1 = d.dummy_date
)
where rownum < 3
) as inner_cursor
FROM (
SELECT CAST( TRUNC(( TO_DATE(:p_start_date, 'DD/MM/YYYY') ) + (ROWNUM) - 1) AS DATE) as dummy_date
FROM all_tab_columns
WHERE ROWNUM <= ( (( TO_DATE(:p_end_date, 'DD/MM/YYYY') - ( TO_DATE(:p_start_date, 'DD/MM/YYYY') )) + 1) * 1 )
) d;
-- i get this error
where t1.c1 = d.dummy_date
*
ERROR at line 7:
ORA-00904: "D"."DUMMY_DATE": invalid identifier
December 09, 2008 - 12:14 pm UTC
CURSOR(
select c1
from (
select c1
from t1
where t1.c1 = d.dummy_date
)
where rownum < 3
) as inner_cursor
you do not need the inline view given your sql.
CURSOR(
select c1
from t1
where t1.c1 = d.dummy_date and rownum < 3
) as inner_cursor
Nested Cursor and Strong Ref Cursor
Ed Girard, April 30, 2009 - 6:44 pm UTC
Below is a package and execution results showing the passing of PL/SQL OUT parameter containing a nested cursor.
The first procedure -
get_Dept_Emps_Weak - uses a weak cursor (SYS_REFCURSOR) which works fine. However, I'd prefer to use a strong ref cursor as demonstrated in the second procedure -
get_Dept_Emps_Strong.
For the sake of compilation I've commented out the version of
get_Dept_Emps_Strong I'd like to use. The procedure
get_Dept_Emps_Strong uses the
dept_Employees_curType record type definition in the spec and this type definition uses the
get_Emp_Job_recType type definition declared previously to hold the employees from the nested cursor. When un-commented, it produces the error "
PLS-00382: expression is of wrong type".
Am I doing something wrong or do nested cursors not support strong (defined) ref cursors when used as a PL/SQL OUT parameter.
Thank you.
scott@dev> CREATE OR REPLACE PACKAGE TEST_NESTED_PKG IS
2
3 -- Type Declarations
4 TYPE get_Emp_Job_recType IS RECORD(
5 emp_Name scott.emp.ename%TYPE,
6 job scott.emp.job%TYPE);
7 TYPE emp_Job_curType IS REF CURSOR RETURN get_Emp_Job_recType;
8
9 TYPE get_Dept_Employees_recType IS RECORD(
10 dept_Name scott.dept.dname%TYPE,
11 employees get_Emp_Job_recType);
12 TYPE dept_Employees_curType IS REF CURSOR RETURN get_Dept_Employees_recType;
13
14
15 -- Procedure Declarations
16 PROCEDURE get_Dept_Emps_Weak(po_Dept_Emps_curVar OUT SYS_REFCURSOR);
17
18 PROCEDURE get_Dept_Emps_Strong(po_Dept_Emps_curVar OUT SYS_REFCURSOR);
19 --PROCEDURE get_Dept_Emps_Strong(po_Dept_Emps_curVar OUT dept_Employees_curType);
20
21 END TEST_NESTED_PKG;
22 /
Package created.
scott@dev> show errors;
No errors.
scott@dev>
scott@dev>
scott@dev> CREATE OR REPLACE PACKAGE BODY TEST_NESTED_PKG IS
2
3 /* Retrieve Departments and Employes in a NESTED Cursor (Weak Ref Cursor */
4 PROCEDURE get_Dept_Emps_Weak(po_Dept_Emps_curVar OUT SYS_REFCURSOR) IS
5 BEGIN
6
7 OPEN po_Dept_Emps_curVar FOR
8 SELECT d1.dname AS dept_Name,
9 CURSOR (SELECT e2.ename,
10 e2.job
11 FROM scott.emp e2
12 WHERE e2.deptno = d1.deptno) employees
13 FROM scott.dept d1;
14
15 END get_Dept_Emps_Weak;
16
17 /* Retrieve Departments and Employes in a NESTED Cursor (Strong Ref Cursor */
18 PROCEDURE get_Dept_Emps_Strong(po_Dept_Emps_curVar OUT SYS_REFCURSOR) IS
19 --PROCEDURE get_Dept_Emps_Strong(po_Dept_Emps_curVar OUT dept_Employees_curType) IS
20 BEGIN
21
22 OPEN po_Dept_Emps_curVar FOR
23 SELECT d1.dname AS dept_Name,
24 CURSOR (SELECT e2.ename,
25 e2.job
26 FROM scott.emp e2
27 WHERE e2.deptno = d1.deptno) employees
28 FROM scott.dept d1;
29
30 END get_Dept_Emps_Strong;
31
32 END TEST_NESTED_PKG;
33 /
Package body created.
scott@dev> show errors;
No errors.
scott@dev>
scott@dev>
scott@dev> var l_test_cursor refcursor
scott@dev>
scott@dev> set autoprint on
scott@dev>
scott@dev> exec TEST_NESTED_PKG.get_Dept_Emps_Weak(:l_test_cursor);
PL/SQL procedure successfully completed.
DEPT_NAME EMPLOYEES
-------------- --------------------
ACCOUNTING CURSOR STATEMENT : 2
CURSOR STATEMENT : 2
ENAME JOB
---------- ---------
CLARK MANAGER
KING PRESIDENT
MILLER CLERK
RESEARCH CURSOR STATEMENT : 2
CURSOR STATEMENT : 2
ENAME JOB
---------- ---------
SMITH CLERK
JONES MANAGER
SCOTT ANALYST
ADAMS CLERK
FORD ANALYST
SALES CURSOR STATEMENT : 2
CURSOR STATEMENT : 2
ENAME JOB
---------- ---------
ALLEN SALESMAN
WARD SALESMAN
MARTIN SALESMAN
BLAKE MANAGER
TURNER SALESMAN
JAMES CLERK
6 rows selected.
OPERATIONS CURSOR STATEMENT : 2
CURSOR STATEMENT : 2
April 30, 2009 - 9:23 pm UTC
the cursor returned by the query is always a weak one - it doesn't have a 'type', it is not bound to any specific type - it's scope is the sql statement.
I don't know of any construct that would let you have this be a strongly typed ref cursor.
what you have is a cursor that returns a varchar and a cursor variable (specifically NOT a varchar and a record - that cursor structure is a varchar + ref cursor)
And if you try to put the ref cursor in there, you'll just get:
LINE/COL ERROR
-------- -----------------------------------------------------------------
10/4 PL/SQL: Declaration ignored
12/7 PLS-00989: Cursor Variable in record, object, or collection is
not supported by this release
Nested Cursor and Strong Ref Cursor
Ed Girard, May 01, 2009 - 10:47 am UTC
Thank you Tom for the fast response.
As you mentioned, the "PLS-00989: Cursor Variable in record, object, or collection is not supported by this release" error is exactly what I too received when I tried to include either a ref cursor or record type in the second TYPE definition.
Regarding the PLS-00989 error: it seems to infer that including a cursor variable in a record or collection may be supported in some future release hence why this type of verbiage. Is this true?
Thank you as always for your assistance.
May 01, 2009 - 11:05 am UTC
is it true that the message indicates that it might be? sure
is it on the drawing board? not that I'm aware of
cursor
A reader, May 01, 2009 - 9:55 pm UTC
Tom:
1. Instead of writing this, can't you just do it in SQL join like
for x in ( select * from users )
loop
for y in ( select * from contacts where userid=x.userid )
loop
...
end loop;
for z in ( select * from addresses where userid=x.userid )
loop
...
end loop;
end loop;
for x in (select * from users a, contacts b, addresses c
where a.userid = b.userid and a.userid=c.userid )
loop
.....
end loop;
2. Also why use CURSOR in SQL. cant we do this like this
select u.userid,
(select contactid from usercontacts where userid=a.userid),
(select addressid from addresses where userid=a.userid)
from users a
instead of this
SELECT U.UserId, U.LoginName, U.PassWord, U.ForeName,
U.SureName, U.Gender, U.Description, U.ModDate,
U.ModUser, DSCore.getState(U.State) AS State,
U.DefaultLanguageId,
CURSOR(SELECT C.UserContactId,
DSCore.getContactType(C.ContactTypeId) AS ContactType,
C.Value, C.Description,
DSCore.getState(C.State) AS State, C.ModUser
FROM UserContacts C
WHERE C.UserId = U.UserId) AS Contacts,
CURSOR(SELECT A.UserAddressId,
DSCore.getAddressType(A.AddressTypeId) AS AddressType,
A.StreetNo, A.ZipCode, A.City, A.Country,
DSCore.getState(A.State) AS State, A.ModUser
FROM UserAddresses A
WHERE A.UserId = U.UserId) AS Addresses
FROM Users U
WHERE U.UserId = pUserId;
May 02, 2009 - 12:07 pm UTC
1) Not in general. If a user has 5 addresses, and 10 contacts your query would return 50 rows (5x10). You would be joining users to addresses (5) and users to contacts (10) and then performing a cartesian join (50) of those two sets.
2) think 1:M relationships please. A user has many addresses. A user has many contacts. A scalar subquery as you suggest can only return 0 or 1 rows - else it raises an error
It is almost 2010; do I need to still do this for the java guys?
Tom, July 20, 2009 - 12:12 pm UTC
The Java front-end team has a typical search screen where the user enters filtering data. The filtering data is passed to a package procedure where I dynamically create the sql statement (utilizing the latest technique from your site 1=1). The Java team is asking me to make changes to my procedure to allow them to pass me another parameter so they can iterate through the data set from certain starting points. They want to re execute the package procedure every time the user scrolls past another 500 records. I have told them I can¿t believe I would need to do this in 2009. I am opening a ref cursor for them and I would think that would suffice.
I have been told that they are using IBATIS and FLEX. They said that they could iterate up and down the ref_cursor if I let them execute the select statement directly against the tables instead of using the stored procedure. I have said no to them at this time and have asked them to do more research on how stateless web apps handle opening and displaying 10 million rows of data without bring all of the data back to the middle in a single download.
Am I correct in telling them ¿No¿. Can you explain to me how the stateless web world and ref_cursors were designed to work together while minimizing unnecessary data movement across the network?
Thank You!
July 24, 2009 - 11:47 am UTC
sounds like their 'framework' would suck all of the data out of the database during the first page (brilliant - no?) and then page through it.
Ask them "is that true" and let us know - cause if it is - say in no uncertain terms "NO"
Function returns more than one value
suriya, May 19, 2011 - 9:38 am UTC
hi tom,
i want function to return more than one value for the following query,i tried using ref cursor but it didn't wrk ..help me tom.
select department_id,job_id,sum(salary) sal from employees group by rollup(department_id,job_id)
May 23, 2011 - 10:37 am UTC
I have no idea what you mean at all. Not a clue.
SQL Course Helo
Shipra, February 01, 2013 - 8:52 am UTC
I am not a programmer but I have this SQL subject this session and have to prepare for it. What all topics should be covered in it?
And has anyone studied from this course www.wiziq.com/course/125-comprehensive-introduction-to-sql of SQL tutorial online?? or tell me any other guidance...
would really appreciate help