Ref cursor return type
i am using a ref cursor as out parameter in a stored procedure.
When I call the stored procedure and want to retrieve the rows returned by the ref cursor,
is there a way to fetch the records using something like %ROWTYPE if I donot know the type of rows returned by the cursor.
eg.
procedure my_test_ref_cursor ( a OUT SYS_REFCURSOR) IS
BEGIN
OPEN a FOR SELECT EMP_ID, EMP_NAME FROM EMP;
END;
procedure call_my_test_ref_cursor is
b sys_refcursor;
begin
my_test_ref_cursor(b);
fetch b into XXXXXXX - if this program doesnot know the type of ref cursor 'b' is pointing to is there a way to use
something like %ROWTYPE here ?
end;
While you can use the logic to return a weakly typed reference cursor, there should be a compelling why. A strongly typed reference cursor may be a better solution. You define a strongly typed reference cursor inside a package, and you anchor it to a ROWTYPE. Weakly typed reference cursors are typically useful when you are working with a subset of a table because you can't anchor to part of a table. However, you can define a view that uses the portion of the table and anchor a strongly typed reference cursor to the view.
A strongly typed PL/SQL reference cursor is defined like this in a package specification:
TYPE strongly_typed_cursor IS REF CURSOR RETURN some_table%ROWTYPE;
So, if you rewrote it like this ...
PROCEDURE my_test_ref_cursor (a OUT SOME_PACKAGE.STRONGLY_TYPED_CURSOR) IS
BEGIN
OPEN a FOR SELECT emp_id, emp_name FROM emp;
END;
Now, you can access it like this ...
PROCEDURE call_my_test_ref_cursor IS
another_var SOME_PACKAGE.STRONGLY_TYPED_CURSOR;
target SOME_TABLE%ROWTYPE;
BEGIN
my_test_ref_cursor(another_var);
LOOP
FETCH another_var INTO target;
EXIT WHEN another_var%NOTFOUND;
dbms_output.put_line('See it '||target.emp_name||'.');
END LOOP;
END;
The DBMS_SQL method you're looking for is Method 4. My recollection is that there isn't a good example in the docs but I could be wrong ... The OCI works no differently, nor does the JDBC interface. Hope this helps.
Similar Messages
-
How to read my cursor that is ref cursor returning user defined type
Hi
I have types defined as follows:
TYPE MY_RECORD IS RECORD (
COL1 TABLE1.COL1%TYPE,
COL2 TABLE1.COL2%TYPE
TYPE MY_CURSOR IS REF CURSOR
RETURN MY_RECORD;This is used as return type in a stored procedure.
I have a pl/sql block where I make a call to the SP that returns this cursor.
How can I read individual values being returned from SP?SQL> create or replace package pkg
as
type my_record is record (col1 emp.empno%type, col2 emp.ename%type);
type my_cursor is ref cursor
return my_record;
procedure p (cur out my_cursor);
end pkg;
Package created.
SQL> create or replace package body pkg
as
procedure p (cur out my_cursor)
as
begin
open cur for
select empno, ename
from emp
where rownum <= 2;
end p;
end pkg;
Package body created.
SQL> declare
cur pkg.my_cursor;
e_rec pkg.my_record;
begin
pkg.p (cur);
loop
fetch cur into e_rec;
exit when cur%notfound;
dbms_output.put ('Empno: ' || e_rec.col1);
dbms_output.put_line ('; Ename: ' || e_rec.col2);
end loop;
close cur;
end;
Empno: 7369; Ename: SMITH
Empno: 7499; Ename: ALLEN
PL/SQL procedure successfully completed. -
DB proc - do you need to create a table to pass a ref cursor record type?
I want to pass a limited selection of columns from a large table through a DB procedure using a REF CURSOR, returning a table rowtype:
CREATE OR REPLACE package XXVDF_XPOS_DS021_ITEMS AS
TYPE XXVDF_XPOS_DS021_ITEM_ARRAY
IS REF CURSOR
return XXVDF_XPOS_DS021_ITEM_TABLE%ROWTYPE;
Do I need to create this dummy table?
I can't get a TYPE to work, where the type is an OBJECT with the desired columns in it.
So a dummy empty table will sit in the database...
Is there another way?
thanks!You can use RECORD type declaration:
SQL> declare
2 type rec_type is record (
3 ename emp.ename%type,
4 sal emp.sal%type
5 );
6 type rc is ref cursor return rec_type;
7 rc1 rc;
8 rec1 rec_type;
9 begin
10 open rc1 for select ename, sal from emp;
11 loop
12 fetch rc1 into rec1;
13 exit when rc1%notfound;
14 dbms_output.put_line(rec1.ename || ' ' || rec1.sal);
15 end loop;
16 close rc1;
17 end;
18 /
SMITH 800
ALLEN 1600
WARD 1250
JONES 2975
MARTIN 1250
BLAKE 2850
CLARK 2450
SCOTT 3000
KING 5000
TURNER 1500
ADAMS 1100
JAMES 950
FORD 3000
MILLER 1300or use, for example, VIEW to declare rowtype:
SQL> create view dummy_view as select ename, sal from emp;
View created.
SQL> declare
2 type rc is ref cursor return dummy_view%rowtype;
3 rc1 rc;
4 rec1 dummy_view%rowtype;
5 begin
6 open rc1 for select ename, sal from emp;
7 loop
8 fetch rc1 into rec1;
9 exit when rc1%notfound;
10 dbms_output.put_line(rec1.ename || ' ' || rec1.sal);
11 end loop;
12 close rc1;
13 end;
14 /
SMITH 800
ALLEN 1600
WARD 1250
JONES 2975
MARTIN 1250
BLAKE 2850
CLARK 2450
SCOTT 3000
KING 5000
TURNER 1500
ADAMS 1100
JAMES 950
FORD 3000
MILLER 1300 Rgds. -
Creating a function having a ref cursor returned
I get an error message for the following code below. I am trying to create a function that allows the users to pass in a certain parameter which is used to invoke a specific query for the paramented passed in. Once the query is invoked, it should return a ref cursor. Please help. I am still using pl/Sql developer.
create or replace package TEST2 is
type rec_DropDownList_Item is RECORD(
TEXT_TYPE VARCHAR2(200),
xsVALUE VARCHAR2(200));
TYPE cur_DropDownList IS REF CURSOR RETURN rec_DropDownList_Item;
FUNCTION Getprocedure_yearreportdisplay (need_type in VARCHAR2) RETURN cur_DropDownList;
end TEST2;
create or replace package body TEST2 is
FUNCTION Getprocedure_yearreportdisplay (need_type in VARCHAR2)
RETURN cur_DropDownList IS
my_ref_cursor cur_DropDownList;
BEGIN
OPEN my_ref_cursor FOR
SELECT vehicletype, vehicledescription
FROM cars where vehicletype = need_type;
return my_ref_cursor;
END Getprocedure_yearreportdisplay;
end TEST2;user13046875 wrote:
a simple example might help because I am having a difficult understanding the reply. Thank you.
create or replace package TEST2 is
type rec_DropDownList_Item is RECORD(
TEXT_TYPE VARCHAR2(200),
xsVALUE VARCHAR2(200));
TYPE cur_DropDownList IS REF CURSOR RETURN rec_DropDownList_Item;
FUNCTION Getprocedure_yearreportdisplay (need_type in VARCHAR2) RETURN cur_DropDownList;
end TEST2;
create or replace package body TEST2 is
FUNCTION Getprocedure_yearreportdisplay (need_type in VARCHAR2)
RETURN cur_DropDownList IS
my_ref_cursor cur_DropDownList;
BEGIN
OPEN my_ref_cursor FOR
SELECT 'column1', 'column2'
FROM dual;
return my_ref_cursor;
END Getprocedure_yearreportdisplay;
end TEST2;
TUBBY_TUBBZ?variable x refcursor;
TUBBY_TUBBZ?
TUBBY_TUBBZ?exec :x := TEST2.Getprocedure_yearreportdisplay('dummy');
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.01
TUBBY_TUBBZ?print :x
'COLUMN 'COLUMN
column1 column2
1 row selected.
Elapsed: 00:00:00.03
TUBBY_TUBBZ?Is an example of running in SQLPLUS (you may want to get your own copy, it's free and available on OTN). -
I have this ref cursor that returns login ids from a procedure.
While I can define the ref cursor as sys_refcursor; I want to use strongly typed ref cursor ( for improved readabilty of code).
But I guess I can not define the cursor that returns %type.
e.g. Type return_login_id IS REF CURSOR return tab1.login_id%type;
On compilation the package threw an error saying the return type should be record.
I need to define a record with one column and use that as return type ?
any other way around ?
TIA
SBtw, why you need to use REF Cursor?
You can use just a cursor:
SQL> declare
2 cursor c1 is select empid from emp;
3 TYPE my_id IS TABLE OF emp.empid%type;
4 myid my_id := my_id();
5 BEGIN
6 OPEN c1;
7 FETCH c1 BULK COLLECT INTO myid;
8 CLOSE c1;
9 END;
10 /
PL/SQL procedure successfully completed.
SQL> -
Pro*C program to use a REF CURSOR returned by a DB Function
Hi,
Please help me with this.
I have a pro*c program that should call a
database function which returns a ref cursor.
This is the sample code i have :-
EXEC SQL BEGIN DECLARE SECTION;
SQL_CURSOR emptycabin_cursor;
int cabinid;
EXEC SQL END DECLARE SECTION;
EXEC SQL ALLOCATE :emptycabin_cursor;
EXEC SQL EXECUTE BEGIN
:emptycabin_cursor:=posremptycabin(:voy,:segid);
END;END-EXEC;
/* more_records = 1*/
while (more_records)
EXEC SQL FETCH :emptycabin_cursor INTO :cabinid;
if (SQLCODE==NOTFOUND)
{more_records=FALSE;break;}
EXEC SQL close :emptycabin_cursor;
When I execute I keep getting fetch out of sequence error.
Can someone let me know whats wrong with this code?
When I execute the function from sqlplus
variable ref_cur refcursor ;
exec :ref_cur:=posremptycabin(232,'CC');
print :ref_cur;
I get the data properly displayed.So nothing wrong with the function.
Thanks for your helpI know nothing about Pro*C, but Tom Kyte's Pro*C example for ref cursors fetches the cursor with a loop that looks like:
for( ;; )
EXEC SQL WHENEVER NOTFOUND DO break;
EXEC SQL FETCH :my_cursor INTO :ename, empno;
printf( "'%.*s', %d\n", ename.len, ename.arr, empno );
EXEC SQL CLOSE :my_cursor;http://asktom.oracle.com/~tkyte/ResultSets/index.html
Hope this helps. -
REF CURSOR RETURNED FROM STORED PROCEDURE OPENED WITH CURRENT_USER PRIVILEGES
Hi.
I was wondering if anyone knows when this bug will be fixed. The bug# is 899567 off of metalink.
I am running into this problem as well, and we do not want to use OCI/SQLNet as the fix. We have an application with secure data concerns and only want to give access to stored procedures to an application user.
Thanks,
BradI'm using version 8.1.6.0.0 on a W2K server.
PS: a strange behaveour
if i try to insert a row using the following anonymous pl/sql block
begin
insert into objects select 2, 'B', ref(c) from meta.classes c where id =1;
end;
i get the following error msg
ERROR at line 1:
ORA-06552: PL/SQL: Compilation unit analysis terminated
ORA-06553: PLS-302: component 'OBJ_T' must be declared
but if i use only the sql command from the sql plus prompt
insert into objects select 2, 'B', ref(c) from meta.classes c where id =1;
the row is inserted.
OBJ_T is the object type(id number, label varchar2, class ref class_t),
OBJECTS is a table of obj_t,
CLASS_T is an object type(id number, label varchar2)
CLASSES is a table of CLASS_T.
null -
Using a strongly typed ref cursor doesn't enforce data type
I am trying to enforce the datatypes of the fields coming back from an oracle reference cursor by making it strongly typed. However, there seems to be no warning at compile time on the oracle side or exception in ODP.NET if the datatype coming back in the cursor does not match. For example here is my cursor and proc
create or replace
PACKAGE THIRDPARTY AS
type pricing_record is record
BaseIndexRate number(6,5),
BaseIndexRateType VARCHAR2(1 BYTE)
type cur_pricing2 IS ref CURSOR return pricing_record;
PROCEDURE getpricingbyappidtest(appid IN application.intid%TYPE, pricing OUT cur_pricing2);
END THIRDPARTY;
create or replace
PACKAGE BODY THIRDPARTY AS
PROCEDURE getpricingbyappidtest(appid IN application.appid%TYPE, pricing OUT cur_pricing2)
AS
BEGIN
OPEN pricing FOR
SELECT somevarcharfield, someothervarcharfield
FROM application
WHERE A.appid = appid;
END getpricingbyappidtest;
I would expect this wouldn't compile since i am putting a varchar into a number field. But it does. Also if i check the datatype in the reader on the .net side it also is a string. So odp doesn't seem to care what type the cursor is
here is that code and output
var schemaTable = reader.GetSchemaTable();
using (var file = new System.IO.StreamWriter("c:\\_DefinitionMap_" + cursorName + ".txt"))
file.WriteLine("COLUMN" + "\t" + "DATATYPE");
foreach (DataRow myField in schemaTable.Rows)
file.WriteLine(myField["ColumnName"] + "\t" + myField["DataType"]);
COLUMN DATATYPE
BaseIndexRate System.String
BaseIndexRateType System.String
Does anyone have an approach for enforcing datatypes in a ref cursor? Am I doing something wrong when defining the ref cursor?Hello,
By using a ref cursor you are really using a pointer to a cursor. There is no way I know of to make a compile check of the cursor check unless you want to create a SQL type and cast the cursor to this type and even this wouldn't work in all cases. For instance, I could have function call within my cursor select which could return a varchar (with a number always in the varchar) which would be horribly sloppy but legal and you would expect Oracle to compile it.
If you are worried about this I would suggest not using ref cursors and go to UDT instead, where there will be more checking (because of a C# equivalence generated object). Oh and BTW, yes the cursor will throw an exception if the data is incorrect, but only at runtime - just like normal Oracle PLSQL.
Cheers
Rob.
http://www.scnet.com.au -
I'm trying to return a REF CURSOR from a function and get the following error:
ORA-00932: inconsistent datatypes: expected CURSER got NUMBER
ORA-06512: at "CERTS.JIMMY", line 17
ORA-06512: at line 10
Here is my function:
CREATE OR REPLACE PACKAGE jimmy
AS
TYPE refc IS REF CURSOR
RETURN equipment%rowtype;
FUNCTION getresults(p_ssan_in IN equipment.ssan%TYPE,
p_type_in IN equipment.equip_type%TYPE)
RETURN refc;
END jimmy;
CREATE OR REPLACE PACKAGE BODY jimmy
AS
FUNCTION getresults( p_ssan_in IN equipment.ssan%TYPE,
p_type_in IN equipment.equip_type%TYPE)
RETURN refc
IS
l_cursor refc;
isretired equipment.retired%TYPE := 'N';
qry varchar2(100) := 'SELECT * ' ||
'FROM equipment ' ||
'WHERE ssan = :b1 ' ||
'AND equip_type = :b2 ' ||
'AND retired = :b3';
BEGIN
EXECUTE IMMEDIATE qry
INTO l_cursor
USING p_ssan_in, p_type_in, isretired;
RETURN l_cursor;
END getresults;
END jimmy;
The data types for the parameters are all varchar2. I don't know why it says it is returning a number.I tried your suggestion:
BEGIN
OPEN l_cursor
FOR qry
USING p_ssan_in, p_type_in, isretired;
RETURN l_cursor;
END getresults;
But I get an error:
PLS-00455: cursor 'L_CURSOR' cannot be used in dynamic SQL OPEN statement -
Returning a Ref cursor as an OUT Parameter
Hi Guys
I have defined 2 Types and 2 Ref cursors as shown below.I have written a procedure having 2 IN and 2 OUT parameters which are of type Ref cursors and return records to the calling client. My question is how can i test for the output of the two cursors here in pl/sql?.. also i should not close the sursors.. right?..its the job of the calling client as per my knowledge....Please suggest
TYPE type_dept_Rec IS RECORD(deptNo varchar2);
TYPE type_prod_Rec IS RECORD(prodType varchar2);
TYPE deptCursor IS REF CURSOR RETURN type_dept_Rec;
TYPE prodCursor IS REF CURSOR RETURN type_prod_Rec;
PROCEDURE TEST (pinCode IN varchar2, prodType IN number, deptCursor OUT deptType, productCursor OUT deptType) IS
BEGIN
OPEN deptCursor FOR SELECT
deptNo
from
DEPT
where
pinCode = pinCode;
OPEN productCursor FOR SELECT
prodCode
from
PROD
where
prodType = prodType;
end;A Correction to the above code snippet
Hi Guys
I have defined 2 Types and 2 Ref cursors as shown below.I have written a procedure having 2 IN and 2 OUT parameters which are of type Ref cursors and return records to the calling client. My question is how can i test for the output of the two cursors here in pl/sql?.. also i should not close the sursors.. right?..its the job of the calling client as per my knowledge....Please suggest
TYPE type_dept_Rec IS RECORD(deptNo varchar2);
TYPE type_prod_Rec IS RECORD(prodType varchar2);
TYPE deptCursor IS REF CURSOR RETURN type_dept_Rec;
TYPE prodCursor IS REF CURSOR RETURN type_prod_Rec;
PROCEDURE TEST (pinCode IN varchar2, prodType IN number, deptCursor OUT deptCursor, productCursor OUT prodCursor) IS
BEGIN
OPEN deptCursor FOR SELECT
deptNo
from
DEPT
where
pinCode = pinCode;
OPEN productCursor FOR SELECT
prodCode
from
PROD
where
prodType = prodType;
end -
OUT parameter of type REF CURSOR
DB: Oracle Database 10g Release 10.2.0.3.0 - Production
OS: Windows xp
I have got these two types:
TYPE myrecord IS RECORD
(column1 tab1.col1%TYPE,
column2 tab1.col2%TYPE
TYPE my_ref_cur IS REF CURSOR RETURN myrecord;Then I have this procedure:
PROCEDURE proc1 (pid IN NUMBER, pout1 OUT my_ref_cur);How can I call the procedure from a pl/sql block and fetch from the cursor variable?
I tried this, but it does not work for me:
DECLARE
lid NUMBER := 748;
lcur1 my_ref_cur
begin
proc1 (lid, lcur1);
end;I receive the error Wrong number or types of arguments in call to 'proc1'
How it must be called?
Thanksseems to work
SQL> create table tab1
2 (col1 number
3 ,col2 number
4 );
Table created.
SQL> insert into tab1 values (1,1);
1 row created.
SQL> commit;
Commit complete.
SQL>
SQL> create or replace package pack
2 is
3 TYPE myrecord IS RECORD
4 (column1 tab1.col1%TYPE,
5 column2 tab1.col2%TYPE
6 );
7 TYPE my_ref_cur IS REF CURSOR RETURN myrecord;
8 procedure proc1 (pid IN number
9 , pout1 OUT my_ref_cur);
10 end pack;
11 /
Package created.
SQL>
SQL> show error
No errors.
SQL>
SQL> create or replace
2 package body pack
3 is
4 procedure proc1 (pid IN number
5 , pout1 OUT my_ref_cur
6 )
7 is
8 begin
9 open pout1
10 for select col1
11 , col2
12 from tab1;
13 end proc1;
14 end pack;
15 /
Package body created.
SQL> show error
No errors.
SQL>
SQL> DECLARE
2 lid NUMBER := 748;
3 lcur1 pack.my_ref_cur;
4 r tab1%rowtype;
5 begin
6 pack.proc1 (lid, lcur1);
7 fetch lcur1 into r;
8 dbms_output.put_line (r.col1||' - '||r.col2);
9 close lcur1;
10 end;
11 /
1 - 1
PL/SQL procedure successfully completed. -
How to return a table to ref cursor?
My client has created a package stored procedure that takes in 2 parameters of VarChar2 and an out parameter which is a table
Following is the package header
CREATE OR REPLACE PACKAGE "PKG_TRAVEL_NEW_SUND" IS
---RECORD TYPE DELARATION
TYPE DIRECT_ALT_REC IS RECORD (SERVICE_NO CBG_DISTANCE_FARE.SERVICE_NO%TYPE,
DISTANCE CBG_DISTANCE_FARE.DISTANCE%TYPE,
CASH_FARE_AC CBG_DISTANCE_FARE.CASH_FARE_AC%TYPE,
CASH_FARE_NON_AC CBG_DISTANCE_FARE.CASH_FARE_NON_AC%TYPE,
CARD_FARE_AC CBG_DISTANCE_FARE.CARD_FARE_AC%TYPE,
CARD_FARE_NON_AC CBG_DISTANCE_FARE.CARD_FARE_NON_AC%TYPE,
EZLINK_FARE_AC CBG_DISTANCE_FARE.EZLINK_FARE_AC%TYPE,
EZLINK_FARE_NON_AC CBG_DISTANCE_FARE.EZLINK_FARE_NON_AC%TYPE,
AVG_RUNTIME CBG_DISTANCE_FARE.AVG_RUNTIME%TYPE,
ALTERNATIVE_NO CBG_DIRECT_ALT.ALTERNATIVE_NO%TYPE,
MAX_FREQ_AM CBG_SVC.MAX_FREQ_AM%TYPE,
MIN_FREQ_AM CBG_SVC.MIN_FREQ_AM%TYPE,
ADVANTAGE_CODE CBG_DIRECT_ALT.ADVANTAGE_CODE%TYPE,
DIST_FARE_CODE_1 CBG_DISTANCE_FARE.DIST_FARE_CODE%TYPE,
DIST_FARE_CODE_2 CBG_DISTANCE_FARE.DIST_FARE_CODE%TYPE,
DIST_FARE_CODE_3 CBG_DISTANCE_FARE.DIST_FARE_CODE%TYPE,
FROM_STOP_CODE CBG_DISTANCE_FARE.FROM_STOP_CODE%TYPE,
TO_STOP_CODE CBG_DISTANCE_FARE.TO_STOP_CODE%TYPE,
MIN_TIME CBG_DIRECT_ALT.MIN_TIME%TYPE,
MIN_FARE CBG_DIRECT_ALT.MIN_FARE%TYPE,
ACT_FARE CBG_DIRECT_ALT.MIN_FARE%TYPE,
TRAVEL_TYPE VARCHAR2(4),
TRANSFER_INFO VARCHAR2(1),
END_TRANSFER_INFO VARCHAR2(1));
--TABLE TYPE DECLARATION
TYPE BUS_INFO_TAB IS TABLE OF DIRECT_ALT_REC INDEX BY BINARY_INTEGER;
-- CURSOR TYPE DECLARATION
TYPE TEMP_REC_STRUCT1 IS RECORD (
RECORD_POSITION BINARY_INTEGER,
DIST_FARE_CODE1 CBG_DISTANCE_FARE.DIST_FARE_CODE%TYPE,
DIST_FARE_CODE2 CBG_DISTANCE_FARE.DIST_FARE_CODE%TYPE,
DIST_FARE_CODE3 CBG_DISTANCE_FARE.DIST_FARE_CODE%TYPE,
ADVANTAGE_CODE CBG_DIRECT_ALT.ADVANTAGE_CODE%TYPE,
MINIMUM_FARE CBG_DIRECT_ALT.MIN_FARE%TYPE,
MINIMUM_TIME CBG_DIRECT_ALT.MIN_TIME%TYPE,
TRAVEL_TYPE VARCHAR2(4) );
TYPE TEMP_TAB_STRUCT1 IS TABLE OF TEMP_REC_STRUCT1 INDEX BY BINARY_INTEGER;
TEMP_TABLE1 BUS_INFO_TAB;
G_RESULTSET_INDEX BINARY_INTEGER := 0 ;
G_TOT_RECS_IN_TAB1 BINARY_INTEGER := 0 ;
TYPE BUS_INFO_CUR IS REF CURSOR RETURN DIRECT_ALT_REC;
---PROCEDURE INSIDE THE PACKAGE
--- PROCEDURE TO SELECT THE RECORDS
PROCEDURE SEL_DIRECT_ALT(P_FROM_STOP_CODE IN VARCHAR2,
P_TO_STOP_CODE IN VARCHAR2,
RESULTSET IN OUT BUS_INFO_TAB);
I'm using ODP.net and here is my code
string storedprocedure = "PKG_TRAVEL_NEW_SUND.SEL_DIRECT_ALT";
//PKG_TRAVEL_NEW_SUND
//CBG003_XP_SP_TEST1
ArrayList retlist = new ArrayList();
OracleConnection curr_conn = this.GetOpenConnection();
OracleCommand cmd = curr_conn.CreateCommand();
cmd = new OracleCommand(storedprocedure, curr_conn);
cmd.CommandType = CommandType.StoredProcedure;
// input parameter
OracleParameter param1 = new OracleParameter();
OracleParameter param2 = new OracleParameter();
param1.ParameterName = "start_code";
param2.ParameterName = "end_code";
param1.OracleDbType = OracleDbType.Varchar2;
param2.OracleDbType = OracleDbType.Varchar2;
param1.Direction = ParameterDirection.Input;
param2.Direction = ParameterDirection.Input;
param1.Size = 5;
param2.Size = 5;
param1.Value = start_codes;
param2.Value = end_codes;
cmd.Parameters.Add(param1);
cmd.Parameters.Add(param2);
OracleParameter outputparam3 = new OracleParameter();
outputparam3.Direction = ParameterDirection.InputOutput;
outputparam3.ParameterName = "output";
outputparam3.OracleDbType = OracleDbType.RefCursor;
// output type
cmd.Parameters.Add(outputparam3);
cmd.ExecuteNonQuery();
At this point, when i execute Query, i get the message telling me that i could have the wrong number or type arguments for the procedure.
I've looked thru countless examples saying i should use a RefCursor, but what else could i miss out?Hi,
This is from Metalink NOTE.219191.1 How to return the values in a PL/SQL table to a ref cursor
Hope it helps,
Greg
This document gives details with an example on how to pass the values
in a PL/SQL table to a ref cursor.
SCOPE & APPLICATION
This document is useful for developers who are familiar with SQL & PL/SQL
How to return the values in a PL/SQL table to a ref cursor
This can be done by using a SQL Object type instead of a PL/SQL table.
Here is an example.
SQL> create or replace type ObjectType as object
2 ( x int,
3 y date,
4 z varchar2(25)
5 );
6 /
Type created.
SQL> create or replace type TabType as table of ObjectType;
2 /
Type created.
SQL> create or replace
2 function demo_function( p_start_row in number,
3 p_end_row in number )
4 return TabType
5 as
6 l_data TabType := TabType();
7 l_cnt number default 0;
8 begin
9 for x in ( select * from emp order by sal desc )
10 loop
11 l_cnt := l_cnt + 1;
12 if ( l_cnt >= p_start_row )
13 then
14 l_data.extend;
15 l_data(l_data.count) :=
16 objectType( x.empno,
17 x.hiredate,
18 x.ename );
19 end if;
20 exit when l_cnt = p_end_row;
21 end loop;
22
23 return l_data;
24 end;
25 /
Function created.
SQL> select *
2 from the ( select cast( demo_function(3,7) as TabType )
3 from dual ) a;
X Y Z
7902 03-DEC-81 FORD
7566 02-APR-81 JONES
7698 01-MAY-81 BLAKE
7782 09-JUN-81 CLARK
7844 08-SEP-81 TURNER
By using a SQL object type, the table can be selected easily.
SQL> create or replace package demo_pkg
2 as
3 type rc is ref cursor;
4
5 procedure p( p_cursor in out rc );
6 end;
7 /
Package created.
SQL> create or replace package body demo_pkg
2 as
3
4 procedure p( P_cursor in out rc )
5 is
6 l_data TabType := TabType();
7 begin
8 for i in 1 .. 3 loop
9 l_data.extend;
10 l_data(i) :=
11 ObjectType( i, sysdate+i, i || ' data');
12 end loop;
13
14 open p_cursor for
15 select *
16 from TABLE ( cast ( l_data as TabType) );
17 end;
18
19 end;
20 /
Package body created.
SQL> set autoprint on
SQL> variable x refcursor
SQL> exec demo_pkg.p(:x)
PL/SQL procedure successfully completed.
X Y Z
1 15-NOV-02 1 data
2 16-NOV-02 2 data
3 17-NOV-02 3 data -
Return csv string as strongly typed ref cursor
I have a column in a table that is csv delimited and I want to return it (and others) as a strongly typed ref cursor.
eg
create table test_tab (mydata varchar2(100))
insert into test_tab(mydata) values ('"a1","b1","c1","d1"')
insert into test_tab(mydata) values ('"a2","b2","c2","d2"')
so test_tab has 1 column and 2 rows:
"a1","b1","c1","d1"
"a2","b2","c2","d2"
So a,b,c,d represent columns in my strongly typed ref cursor
If I then try something like:
declare
type my_rec is record(
a varchar2(50),
b varchar2(50),
c varchar2(50),
d varchar2(50)
type my_rec_refc IS REF CURSOR RETURN my_rec;
my_test_refc my_rec_refc;
begin
open my_test_refc for select mydata,mydata,mydata,mydata from test_tab;
end;
then it obviously works as my ref cursor is expecting 4 columns. However, what I want to do is break each individual element out of the mydata column. I've played around a bit with dynamic sql but only getting so far and apparently that can't be used with a ref cursor anyway. I need to return a strongly typed cursor as another program requires this.
One option is to manually parse each row and insert into temp table that is basically definition of record (so record type no longer needed) and this becomes type of ref cursor. I can then simply select from the table. I'm not keen on this as it's just another object to worry about.
Another option is to do some ugly instr/substr to extract each element in the sql statement (or write a function to do it but need to consider performance of this). The more generic the better as I need to reuse against multiple strongly typed ref cursors (kind of a contradiction in that by virtue of using strongly typed cursors I know exactly what I want returned!).
Another option is for someone to shed some light on this as it must be possible to do in a simple way along the same lines I have started?
thanks in advanceThat documentation seems to stay pretty vague. What constitutes the "right set of columns". Obviously my observed result matches what you are saying about not being able to enforce the datatypes in the fields of the strong typed cursor. But then I don't see the point of the strong typed cursor otherwise. Other sites i have read seem to focus on the %rowtype return rather than mapping it to a record. But the general consensus (at least to my understanding) is that if the cursor is strongly typed then the sql statement that used to open it must have the same set of columns and the datatypes must at least be able to implicitly convert.
I will try the %rowtype strong ref cursor against a table and see if there is a different result. I am mainly interested in this because I would like to beable to ensure the datatype returned on the .net side through ODP
I want to be able to know the datatype of a field coming back through a ref cursor at compile time not runtime. So it the answer to cast every field of the select statement? -
Ref Cursor closed returning to Form
Hi,
I came across this old thread which seems to be an exact match for my problem.
sys ref cursor is closed
And whereas the solutions do work as stated there is an issue with it that i wonder if anyone here has since got around.
Take those examples and make the sql dynamic. on return to the form the ref cursor is instantaneouly closed for you making the thing unusable.
i.e.
OPEN cur FOR SELECT 'x' from dual
works just fine but
OPEN cur FOR 'SELECT ''X'' from dual'
resutls in an closed cursor the moment the ref cursor parameter returns to the form. I need the dynamic form because my cursor is truly built dynamically.
Any ideas anyone?Hi,
try this :
1. declare in the package specification
TYPE rec_view IS RECORD(
COL1 VARCHAR2(250),
COL2 VARCHAR2(250),
COL3 VARCHAR2(250),
COL4 VARCHAR2(250),
COL5 VARCHAR2(250)
TYPE t_ref_curs IS REF CURSOR RETURN rec_view;
TYPE t_rec_c IS REF CURSOR;
2. define the dynamic sql - procedure
PROCEDURE prc_getdata (p_refcur IN OUT t_ref_curs, p_result OUT VARCHAR2,
p_filter IN varchar2 DEFAULT NULL, p_orderby In VARCHAR2 DEFAULT NULL) IS
BEGIN
-- dyn cursor ! --
EXECUTE IMMEDIATE
'BEGIN
OPEN :a FOR ' ||
' select empno, ename, job, mgr, hiredate, sal from emp'||' '||
p_filter ||' '||
p_orderby ||'; '||
'END;'
USING p_refcur;
END prc_getdata;
3. define in the Form a PL/SQL based block on this procedure.
Hope it helps.
Best regards
Friedhold -
How to handle the ref cursor which is returning "no rows"
I have written a function which is returning the REF CURSOR. But in one situation the REF CURSOR returns "no rows selected". To handle this situation an exception is raised "when no data found". But i dont know in this situation how should NULL cursor be returned through this function. Since I want to call this function in another procedure so something should be returned through this function by means of ref cursor. But since i am not able to handle this "no rows selected" situation i am not able move further.
Thanks in advance........I agree.
You would simply process the returned ref cursor irrespective of any rows actually returned in the cursor or not. You would be able to do at least one FETCH from the cursor (even if it does not actually contain any rows) and then determine the %NOTFOUND status to do the rest of the processing.
SQL> variable cur refcursor
SQL> exec open :cur for select * from scott.emp where rownum = 1 ;
PL/SQL procedure successfully completed.
SQL> print cur
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
7369 SMITH CLERK 7902 17-DEC-1980 800 20
1 row selected.
SQL>
SQL> exec open :cur for select * from scott.emp where 1 = 2 ;
PL/SQL procedure successfully completed.
SQL> print cur
no rows selected
SQL>
SQL> SET SERVEROUTPUT ON
SQL> DECLARE
2 rec scott.emp%ROWTYPE;
3 bol BOOLEAN;
4 cur sys_refcursor;
5 BEGIN
6 OPEN cur FOR
7 SELECT * FROM scott.emp WHERE 1 = 2; /* assume this is your function call returning a ref cursor */
8 bol := FALSE;
9 LOOP
10 FETCH cur
11 INTO rec;
12 EXIT WHEN cur%NOTFOUND;
13 --
14 -- process the data here
15 --
16 bol := TRUE;
17 END LOOP;
18 CLOSE cur;
19 IF (bol)
20 THEN
21 dbms_output.put_line('At least one row was found');
22 ELSE
23 dbms_output.put_line('No rows were selected');
24 END IF;
25 END;
26 /
No rows were selected
PL/SQL procedure successfully completed.
SQL>
Maybe you are looking for
-
The "FIND" feature in the Edit menu does not work. I can't find anything on a webpage
The "FIND" feature in the Edit menu does not work. I cannot search a page. If I am looking for the word "Doctor" and I know it is on the page. All I get after typing the first letter is that the typing box turns red. This is not fun.
-
Cannot save alias. The alias cannot be saved at this time.
I'm trying to create an alias and cannot. Error is title of this post. I've searched this issue in the support community and only see similar issues as recent as 2013 and 2012. I'm wondering if there is any support for this issue. Thanks!
-
Can I connect the latest iMacs to HDTV? Can the miniDisplay/Thunderbold port be used to output Audio & Video? Also, if I were to use the iMac as a monitor for a PC, can it be done?
-
CS 5 InDesign can't get the tutorial to work
I'm new to CS5 InDesign. I want to do the tutorial but when it tries to load it says I need an updated version of "Flash" I have uninstalled flash and reinstalled several time. The version that I downloaded is version 10.2.159.1 But when I check on
-
HT201303 I need my existing account to have "None" as the payment option - any suggestions
I need my existing itunes account to have "None" as a payment option. Any suggestions? Thanks