WEAK REF CURSOR type
This is the first time I have a need at work to use a REF CURSOR type of the weak variety. After reading documentation
in SF's 'bible' Oracle PL/SQL Programming, I did everything right. Here's the code snippet:
-- TYPES
TYPE content_ID_curtype IS
REF CURSOR;
-- VARIABLES
c_SEARCH_STRING CONSTANT VARCHAR2(12) := 'v_content_id';
content_ID_cur content_ID_curtype;
v_content_ID am_content_content.content_ID%TYPE;
BEGIN
cache_sql_rec.sql_stmt := REPLACE(cache_sql_rec.sql_stmt, c_SEARCH_STRING, template_name_rec.content_ID);
OPEN content_ID_cur FOR cache_sql_rec.sql_stmt;
LOOP
FETCH content_ID_cur
INTO v_content_ID;
EXIT WHEN content_ID_cur%NOTFOUND;
END LOOP;
CLOSE content_ID_cur;
END;
Now the error I get is.... ORA-00911: invalid character When I used DBMS_OUTPUT to see the actual value of
"cache_sql_rec.sql_stmt", the SQL query looks fine. Even when I hardcoded the sql statement after the FOR keyword, it
worked fine. It's only when I use a variable to hold the whole SQL statement does it fail. Here's one value for the
variable cache_sql_rec.sql_stmt:
SELECT b.content_id
FROM am_content_mofcollection a,
am_content_collection b
WHERE a.content_id = 149090
AND a.collection_id = b.collection_id;
Basically I replace the string with an actual content_ID. Now content_ID is of type NUMBER(12) as is the variable
v_content_ID declared so that I FETCH INTO that variable, but the problem is, is that the exception gets raised during
the OPEN...cursor...FOR....sql_statement command.
Any thoughts on this bug?
Thanks,
Gio
Giovanni Jaramillo
Senior Software Engineer
Oracle Database Group
Amplified Holdings, Inc.
5750 Wilshire Blvd., Ste 501
Los Angeles, CA 90036-3638
(323)-556-8792
[email protected] http://www.amplified.com
Yes it turns out that the data had a semicolon at the end since it's being inserted by someone else. I know when executing DDL or DML statements via NDS you omit the semicolon. But didn't know it applied to REF CURSORS.
Also I added a colon to the variable that I was REPLACING since it can act as a bind variable.
Thanks Andrew.
Gio
null
Similar Messages
-
I want to implement a stored procedure which takes a
weak ref cursor as one of its IN parameters. In the body
of the SP I want to analyze the "structure" of the weak
ref cursor: column names and types.
Any hints how to do this in PL/SQL?? Of course, in C via OCI
describing a (weak) ref cursor at run-time is no problem at
all.
Tobias.it is not possible to fetch into some variable, which doesn't match the structure of the cursor variable.....
There is one way.....you can discard the first n records while assigning the query to cursor variable....
Frame ur query that ur going to assocaite to the cursor in the following way....
select * from (select rownum a, test.* from test) where a > N
where 'N' is the no of records that u don't want to be in the cursor.....
if u have doubt in this approach get back to me... -
Weak REF CURSOR: discarding records?
Hi,
I'd like to discard the first N records from a weak REF CURSOR without having to specify the structure of the cursor. Is this possible?
For example:
LOOP
FETCH results INTO garbagecan
EXIT WHEN results%NOTFOUND;
END LOOP;
It seems that FETCH statement requires INTO to be specified with the correct structure.
-Jerome
nullit is not possible to fetch into some variable, which doesn't match the structure of the cursor variable.....
There is one way.....you can discard the first n records while assigning the query to cursor variable....
Frame ur query that ur going to assocaite to the cursor in the following way....
select * from (select rownum a, test.* from test) where a > N
where 'N' is the no of records that u don't want to be in the cursor.....
if u have doubt in this approach get back to me... -
Stored PL/SQL function that returns REF CURSOR type
Hello everyone,
I've come through the following problem:
1.- I created an PL/SQL stored procedure which returns a REF CURSOR element, definition looks like this:
PACKAGE PKG_LISTADOS AS
TYPE tuplas IS REF CURSOR;
/* Procedimientos exportados por el paquete */
PROCEDURE inicializarModuloListados;
FUNCTION recaudacionUltimoMes(medioPago DEF_MEDIO_PAGO.MEDIO_PAGO%TYPE)
RETURN tuplas;
2.- Now I would like to call the stored procedure and retrieve the PL/SQL cursor as a ResultSet Java Object. The code I wrote is this:
Connection conn;
XmlDocument paramDef;
conn=poolMgr.getConnection str_poolDBConnection);
try
CallableStatement cstmt=conn.prepareCall("{?=call PKG_LISTADOS.recaudacionUltimoMes(?)}");
cstmt.registerOutParameter(1, java.sql.Types.OTHER);
cstmt.setString(2, "MONEDA");
cstmt.executeQuery();
ResultSet rs=(ResultSet)cstmt.getObject(1);
catch(SQLException sqlE)
3.- However, I can't make it OK, all the time I get the following error:
SQL Error(17004), java.sql.SQLException: Non valid column type
May anyone help me with this, thanks in advance:
Miguel-Angel<BLOCKQUOTE><font size="1" face="Verdana, Arial">quote:</font><HR>Originally posted by angelrip:
Hello everyone,
I've come through the following problem:
1.- I created an PL/SQL stored procedure which returns a REF CURSOR element, definition looks like this:
PACKAGE PKG_LISTADOS AS
TYPE tuplas IS REF CURSOR;
/* Procedimientos exportados por el paquete */
PROCEDURE inicializarModuloListados;
FUNCTION recaudacionUltimoMes(medioPago DEF_MEDIO_PAGO.MEDIO_PAGO%TYPE)
RETURN tuplas;
2.- Now I would like to call the stored procedure and retrieve the PL/SQL cursor as a ResultSet Java Object. The code I wrote is this:
Connection conn;
XmlDocument paramDef;
conn=poolMgr.getConnection str_poolDBConnection);
try
CallableStatement cstmt=conn.prepareCall("{?=call PKG_LISTADOS.recaudacionUltimoMes(?)}");
cstmt.registerOutParameter(1, java.sql.Types.OTHER);
cstmt.setString(2, "MONEDA");
cstmt.executeQuery();
ResultSet rs=(ResultSet)cstmt.getObject(1);
catch(SQLException sqlE)
3.- However, I can't make it OK, all the time I get the following error:
SQL Error(17004), java.sql.SQLException: Non valid column type
May anyone help me with this, thanks in advance:
Miguel-Angel<HR></BLOCKQUOTE>
Do something like the following:
cstmt = conn.prepareCall("{call customer_proc(?, ?)}");
//Set the first parameter
cstmt.setInt(1, 40);
//Register to get the Cursor parameter back from the procedure
cstmt.registerOutParameter(2, OracleTypes.CURSOR);
cstmt.execute();
ResultSet cursor = ((OracleCallableStatement)cstmt).getCursor(2);
while(cursor.next())
System.out.println("CUSTOMER NAME: " + cursor.getString(1));
System.out.println("CUSTOMER AGE: " + cursor.getInt(2));
cursor.close();
null -
Hello All,
I have a small procedure like the following.
CREATE OR REPLACE procedure PROC_DEPT_SALE(SALEC_CUR out sys_refcursor)
as
begin
open sale for select * from dept_sale where dept_no='Z2341324';
end;
I just want to execute it from toad like
exec PROC_DEPT_SALE( C1);
In order to do that i need to have a sys_refcursor c1 created in my DB. I know that i can execute it as a plsql block like this
DECLARE
SALE SYS_REFCURSOR;
BEGIN
PROC_DEPT_SALE( SALE );
END;
Could anyone please let me know how can i create a TYPE REF cursor which is permanantly stored in the DB and then execute the proc the way i wanted to using the first statement.
ThanksActually, you had it correct with
CREATE OR REPLACE package cur_type as
TYPE ref_cur IS REF CURSOR;
end;but you still need to declare a variable of the type to pass the the procedure since the procedure needs to have a cursor variable to open. Given your package, the call would be more like:
DECLARE
l_cur cur_type.ref_cur;
BEGIN
proc_dept_sale(l_cur);
<do something with l_cur>
END;Forget about the cursor for a minute and think through this example. If I have a procedure that looks like:
CREATE PROCEDURE get_name (p_id IN NUMBER,
p_name OUT VARCHAR2) AS
BEGIN
SELECT last_name||', '||first_name
INTO p_name
FROM employee
WHERE emp_id = p_id;
END;I can pass a literal value to the procedure for the p_id parameter (e.g. 42) or I could pass a variable holding a value.
What do I need to pass to the procedure in p_name to get the name back out? A procedure returning a cursor is no different than this in concept.
John -
Ref cursor vs sys_refcursor
What is the diffeerenece between ref cursor and sys_refcursor.in which scenarios we use ref cusor and sys_refcursor with example.For the performace point of view which is better.
BluShadow wrote:
SAMBIT RAY wrote:
Hi,
thanks for use ful difference.
i got your difference between two but as per performace level which is better.plz suggestAs billy said they are all cursors.
As my link highlights, a ref cursor of any sort is just a pointer to a query.
SYS_REFCURSOR is just a synonym for the REF CURSOR type.
There is no performance difference.Putting on my nit picking hat :-)
Sys_refcursor is a named type of type refcursor. The $ORACLE_HOME/rdbms/admin/stdspec.sql ther is this line:
/* Adding a generic weak ref cursor type */
type sys_refcursor is ref cursor;Since it is in package standard we can use it without qualifying it with a package name, but
declare
l_cur sys_refcursor;is exactly the same as:
reate package my_pack as
type john_cursor is ref cursor;
end;
declare
l_cur my_pack.john_cursor;Taking off my nit picking hat now.
John -
Cursor difference (REF Cursor & Sys_Refcursor)
Hi,
Is there any difference between REF Cursor and SYS_Refcursor?
I see some packages using sys_refcursor and some using REF Cursor.
Package 1 (Spec):
PROCEDURE s_demo1 (
ret_rset OUT sys_refcursor
Package 2 (Spec):
TYPE cur_set IS REF CURSOR;
PROCEDURE s_test1 (out_data OUT cur_set);
PROCEDURE s_test2 (out_data OUT cur_set);I am going through this link (http://sql-plsql.blogspot.com/2007/05/oracle-plsql-ref-cursors.html) but didn't find the answer.DomBrooks wrote:
John - don't get me wrong, I'm not suggesting that as soon as something like SYS_REFCURSOR comes along, everything should get rewritten. It's just I still see new packages written on 11g by, say mainly C# or java developers, which use this old style.
But.... are you saying that you can't do this?
CREATE OR REPLACE PACKAGE old_package AS
TYPE pkg_cur IS REF CURSOR;
FUNCTION foo(p_id IN NUMBER) RETURN sys_refcursor;
END;
CREATE OR REPLACE PACKAGE BODY old_package AS
FUNCTION foo(p_id IN NUMBER) RETURN sys_refcursor IS
l_cur sys_refcursor;
BEGIN
OPEN l_CUR FOR SELECT * FROM dual WHERE 1 = p_id;
RETURN l_cur;
END;
END;
Absolutely, I can even declare pkg_cursor as a sys_refcursor and all of the old calls will still work since sys_refcursor is just a ref cursor in disguise. What I cannot do is drop the declaration in the package spec since the outside callers rely on it, so since sys_refcusor is just a ref cursor in disguise, why use it?
In fact, in OHOME/rdbms/admin/stdspec.sql which is the declarations for the package standard sys_refcursor is declared as:
/* Adding a generic weak ref cursor type */
type sys_refcursor is ref cursor;Since things declared in standard package (like data types, operators, all of the named exceptions etc.) are "globally" available without using the package name, sys_refcursor just provides a method to save a few keystrokes everywhere. It is no different functionally than a package declared ref cursor. The main difference is that you cannot create a strongly typed sys_refcursor, if you want/need one, you need to use a ref cursor.
I do tend to use sys_refcursor in new code, but it took me a while to switch because there is not much real benefit as far as I can see.
John
Edited by: John Spencer on Nov 17, 2010 4:11 PM -
I have two packages (please see below). A procedure from the first package (TEST1) calls a procedure in the second package (TEST2), which has an output parameter of REF CURSOR TYPE.
I am getting an error at compile time, in the calling procedure.
Can anyone please help on finding out what am I missing here?
Thank you in advance.
- Ketan Bhuptani
Here are the procedures:
(1)
CREATE OR REPLACE PACKAGE TEST1
AS
TYPE cursor_type_pass IS REF CURSOR;
PROCEDURE call_cursor (result_flag OUT varchar2);
END TEST1;
CREATE OR REPLACE PACKAGE BODY TEST1
AS
PROCEDURE call_cursor (result_flag OUT varchar2) IS
v_salary int;
proc_cursor cursor_type_pass;
CURSOR emp_cur is select empid from emp;
BEGIN
FOR emp_cur_var IN emp_cur
LOOP
test2.open_cursor(emp_cur_var.empid, proc_cursor);
v_salary := proc_cursor.salary;
-- getting an error Invalid reference to variable proc_cursor at this line
END LOOP;
END call_cursor;
END TEST1;
(2)
CREATE OR REPLACE PACKAGE TEST2
AS
TYPE cursor_type_return IS REF CURSOR;
PROCEDURE open_cursor (emp_id IN varchar2, out_cur OUT cursor_type_return);
END TEST2;
CREATE OR REPLACE PACKAGE BODY TEST2
AS
PROCEDURE open_cursor (emp_id IN varchar2, out_cur OUT cursor_type_return) IS
BEGIN
OPEN out_cur FOR
select location, salary from emp_information where empid = emp_id;
END open_cursor;
END TEST2;
create table emp_information
(location varchar2(30), salary int, empid varchar2(10));
create table emp
(empid varchar2(10));Your scenario is not very clear to me, but let us do some test coding here, see if it helps you,SQL> create or replace package test_pkg1 as
2 TYPE cursor_type1 IS REF CURSOR;
3 procedure proc1;
4 end;
5 /
Package created.
SQL> create or replace package test_pkg2 as
2 TYPE cursor_type2 IS REF CURSOR;
3 procedure proc2(pCur IN OUT cursor_type2);
4 end;
5 /
Package created.
SQL> create or replace package body test_pkg2 as
2 procedure proc2(pCur IN OUT cursor_type2) is
3 begin
4 open pCur for SELECT ename from my_emp;
5 end;
6 end;
7 /
Package body created.
SQL> create or replace package body test_pkg1 as
2 procedure proc1 is
3 vRefCur cursor_type1;
4 vEname VARCHAR2(20);
5 vRefCur2 test_pkg2.cursor_type2;
6 begin
7 test_pkg2.proc2(vRefCur); -- this is possible, but I do not like it.
8 vRefCur2 := vRefCur; -- you can also do this, but you have no reason to do this
9 loop
10 fetch vRefCur2 into vEname;
11 exit when vRefCur2%NOTFOUND;
12 dbms_output.put_line(vEname);
13 end loop;
14 close vRefCur2;
15 end;
16 end;
17 /
Package body created.
SQL> exec test_pkg1.proc1;
SMITH
ALLEN
WARD
JONES
MARTIN
BLAKE
CLARK
SCOTT
KING
TURNER
ADAMS
JAMES
FORD
MILLER
PL/SQL procedure successfully completed.
Let us make it simple,
SQL> create or replace package body test_pkg1 as
2 procedure proc1 is
3 vRefCur cursor_type1;
4 vEname VARCHAR2(20);
5 --vRefCur2 test_pkg2.cursor_type2;
6 begin
7 test_pkg2.proc2(vRefCur);
8 --vRefCur2 := vRefCur;
9 loop
10 fetch vRefCur into vEname;
11 exit when vRefCur%NOTFOUND;
12 dbms_output.put_line(vEname);
13 end loop;
14 close vRefCur;
15 end;
16 end;
17 /
Package body created.
SQL> exec test_pkg1.proc1;
SMITH
ALLEN
WARD
JONES
MARTIN
BLAKE
CLARK
SCOTT
KING
TURNER
ADAMS
JAMES
FORD
MILLER
PL/SQL procedure successfully completed.You can play with it number of different ways.
Let me know what questions and we will take it from there.
Thx,
SriDHAR -
How can I iterate over the columns of a REF CURSOR?
I have the following situation:
DECLARE
text VARCHAR2 (100) := '';
TYPE gen_cursor is ref cursor;
c_gen gen_cursor;
CURSOR c_tmp
IS
SELECT *
FROM CROSS_TBL
ORDER BY sn;
BEGIN
FOR tmp IN c_tmp
LOOP
text := 'select * from ' || tmp.table_name || ' where seqnum = ' || tmp.sn;
OPEN c_gen FOR text;
-- here I want to iterate over the columns of c_gen
-- c_gen will have different number of columns every time,
-- because we select from a different table
-- I have more than 500 tables, so I cannot define strong REF CURSOR types!
-- I need something like
l := c_gen.columns.length;
for c in c_gen.columns[1]..c_gen.columns[l]
LOOP
-- do something with the column value
END LOOP;
END LOOP;
END;As you can see from the comments in the code, I couln'd find any examples on the internet with weak REF CURSORS and selecting from many tables.
What I found was:
CREATE PACKAGE admin_data AS
TYPE gencurtyp IS REF CURSOR;
PROCEDURE open_cv (generic_cv IN OUT gencurtyp, choice INT);
END admin_data;
CREATE PACKAGE BODY admin_data AS
PROCEDURE open_cv (generic_cv IN OUT gencurtyp, choice INT) IS
BEGIN
IF choice = 1 THEN
OPEN generic_cv FOR SELECT * FROM employees;
ELSIF choice = 2 THEN
OPEN generic_cv FOR SELECT * FROM departments;
ELSIF choice = 3 THEN
OPEN generic_cv FOR SELECT * FROM jobs;
END IF;
END;
END admin_data;
/But they have only 3 tables here and I have like 500. What can I do here?
Thanks in advance for any help!The issue here is that you don't know your columns at design time (which is generally considered bad design practice anyway).
In 10g or before, you would have to use the DBMS_SQL package to be able to iterate over each of the columns that are parsed from the query... e.g.
CREATE OR REPLACE PROCEDURE run_query(p_sql IN VARCHAR2) IS
v_v_val VARCHAR2(4000);
v_n_val NUMBER;
v_d_val DATE;
v_ret NUMBER;
c NUMBER;
d NUMBER;
col_cnt INTEGER;
f BOOLEAN;
rec_tab DBMS_SQL.DESC_TAB;
col_num NUMBER;
v_rowcount NUMBER := 0;
BEGIN
-- create a cursor
c := DBMS_SQL.OPEN_CURSOR;
-- parse the SQL statement into the cursor
DBMS_SQL.PARSE(c, p_sql, DBMS_SQL.NATIVE);
-- execute the cursor
d := DBMS_SQL.EXECUTE(c);
-- Describe the columns returned by the SQL statement
DBMS_SQL.DESCRIBE_COLUMNS(c, col_cnt, rec_tab);
-- Bind local return variables to the various columns based on their types
FOR j in 1..col_cnt
LOOP
CASE rec_tab(j).col_type
WHEN 1 THEN DBMS_SQL.DEFINE_COLUMN(c,j,v_v_val,2000); -- Varchar2
WHEN 2 THEN DBMS_SQL.DEFINE_COLUMN(c,j,v_n_val); -- Number
WHEN 12 THEN DBMS_SQL.DEFINE_COLUMN(c,j,v_d_val); -- Date
ELSE
DBMS_SQL.DEFINE_COLUMN(c,j,v_v_val,2000); -- Any other type return as varchar2
END CASE;
END LOOP;
-- Display what columns are being returned...
DBMS_OUTPUT.PUT_LINE('-- Columns --');
FOR j in 1..col_cnt
LOOP
DBMS_OUTPUT.PUT_LINE(rec_tab(j).col_name||' - '||case rec_tab(j).col_type when 1 then 'VARCHAR2'
when 2 then 'NUMBER'
when 12 then 'DATE'
else 'Other' end);
END LOOP;
DBMS_OUTPUT.PUT_LINE('-------------');
-- This part outputs the DATA
LOOP
-- Fetch a row of data through the cursor
v_ret := DBMS_SQL.FETCH_ROWS(c);
-- Exit when no more rows
EXIT WHEN v_ret = 0;
v_rowcount := v_rowcount + 1;
DBMS_OUTPUT.PUT_LINE('Row: '||v_rowcount);
DBMS_OUTPUT.PUT_LINE('--------------');
-- Fetch the value of each column from the row
FOR j in 1..col_cnt
LOOP
-- Fetch each column into the correct data type based on the description of the column
CASE rec_tab(j).col_type
WHEN 1 THEN DBMS_SQL.COLUMN_VALUE(c,j,v_v_val);
DBMS_OUTPUT.PUT_LINE(rec_tab(j).col_name||' : '||v_v_val);
WHEN 2 THEN DBMS_SQL.COLUMN_VALUE(c,j,v_n_val);
DBMS_OUTPUT.PUT_LINE(rec_tab(j).col_name||' : '||v_n_val);
WHEN 12 THEN DBMS_SQL.COLUMN_VALUE(c,j,v_d_val);
DBMS_OUTPUT.PUT_LINE(rec_tab(j).col_name||' : '||to_char(v_d_val,'DD/MM/YYYY HH24:MI:SS'));
ELSE
DBMS_SQL.COLUMN_VALUE(c,j,v_v_val);
DBMS_OUTPUT.PUT_LINE(rec_tab(j).col_name||' : '||v_v_val);
END CASE;
END LOOP;
DBMS_OUTPUT.PUT_LINE('--------------');
END LOOP;
-- Close the cursor now we have finished with it
DBMS_SQL.CLOSE_CURSOR(c);
END;
SQL> exec run_query('select empno, ename, deptno, sal from emp where deptno = 10');
-- Columns --
EMPNO - NUMBER
ENAME - VARCHAR2
DEPTNO - NUMBER
SAL - NUMBER
Row: 1
EMPNO : 7782
ENAME : CLARK
DEPTNO : 10
SAL : 2450
Row: 2
EMPNO : 7839
ENAME : KING
DEPTNO : 10
SAL : 5000
Row: 3
EMPNO : 7934
ENAME : MILLER
DEPTNO : 10
SAL : 1300
PL/SQL procedure successfully completed.
SQL> exec run_query('select * from emp where deptno = 10');
-- Columns --
EMPNO - NUMBER
ENAME - VARCHAR2
JOB - VARCHAR2
MGR - NUMBER
HIREDATE - DATE
SAL - NUMBER
COMM - NUMBER
DEPTNO - NUMBER
Row: 1
EMPNO : 7782
ENAME : CLARK
JOB : MANAGER
MGR : 7839
HIREDATE : 09/06/1981 00:00:00
SAL : 2450
COMM :
DEPTNO : 10
Row: 2
EMPNO : 7839
ENAME : KING
JOB : PRESIDENT
MGR :
HIREDATE : 17/11/1981 00:00:00
SAL : 5000
COMM :
DEPTNO : 10
Row: 3
EMPNO : 7934
ENAME : MILLER
JOB : CLERK
MGR : 7782
HIREDATE : 23/01/1982 00:00:00
SAL : 1300
COMM :
DEPTNO : 10
PL/SQL procedure successfully completed.
SQL> exec run_query('select * from dept where deptno = 10');
-- Columns --
DEPTNO - NUMBER
DNAME - VARCHAR2
LOC - VARCHAR2
Row: 1
DEPTNO : 10
DNAME : ACCOUNTING
LOC : NEW YORK
PL/SQL procedure successfully completed.
SQL>From 11g onwards, you can create your query as a REF_CURSOR, but then you would still have to use the DBMS_SQL package with it's new functions to turn the refcursor into a dbms_sql cursor so that you can then describe the columns in the same way.
http://technology.amis.nl/blog/2332/oracle-11g-describing-a-refcursor
Welcome to the issues that are common when you start to attempt to create dynamic code. If your design isn't specific then your code can't be either and you end up creating more work in the coding whilst reducing the work in the design. ;) -
Ref cursors in Database adapter
Hi,
Is the database adapter capable of handling ref cursors as the datatype of the output parameters of a pl/sql procedure?
For instance if I have the following in my package-spec:
TYPE SomeRecordType IS RECORD
( record_pk mut_table.record_pk%TYPE
, person_nr person_table.person_nr%TYPE
, field_1 mut_table.field_1%type
, field_2 mut_table.field_2%type
, field_3 mut_table.field_3%type
TYPE SomeCursorType IS REF CURSOR RETURN SomeRecordType;
PROCEDURE read_records
( cursor_out OUT SomeCursorType
, exception_code OUT number
, exception_message OUT varchar2
Can the database adapter call the read_records procedure?
I've never seen this in any doc. I know it can't handle record types (that is in 10.1.2 it couldn't as far as I know). So I figure that the above is not possible.
Thanks in advance.
Regards,
MartienWe have successfully used a sys_refcursor OUT parameter for a database procedure call and which is used by a DBAdapter to return a single dataset.
At the time I remember attempting to use a strongly typed ref cursor as the parameter. I think this is what you are attempting to do. I rejected this approach at the time as I was not able to do this. It was, in our case, as simple as using the system defined ref cursor type (i.e. weakly typed).
The handling of the returned dataset was not immediately obvious, but can be handled by as fairly simple XSL transformation to a locally defined variable of the requisite xml structure. I won't describe in detail how to do it as it is specific to our process. Suffice to say the transformation loops over all result rows assign via a test to the correct result field in our local variable.
e.g.
<xsl:template match="/">
<ns1:BatchRequest004>
<xsl:for-each select="/db:OutputParameters/db:P_SCHSHP_REF_CUR/db:Row">
<ns1:statusRqst>
<xsl:if test='db:Column/@name = "ID"'>
<xsl:attribute name="id">
<xsl:value-of select="db:Column[1.0]"/>
</xsl:attribute>
</xsl:if>
</ns1:statusRqst>
</xsl:for-each>
</ns1:BatchRequest004>
HTH and that I haven't misidentified your problem. -
Is there a different way to open a cursor for a ref cursor procedure?
hello everybody
i have two cursors, cur_a and cur_b, declared somewhere else in my application.
These two cursors have the same fields, in the same order, and i have to treat both in the same way. So i wrote a routine that gets as input a ref cursor based on the cur_a rowtype, and i am trying to use this routine for both.
The problem is that i am not able to open outside the routine the cursor in a different way than usual...
the common method is :
declare curs ref cursor ...
begin
open curs for (select *...)
end;
instead i would like to obtain something different
declare curs ref cursor ...
begin
open curs for cur_a
end;hi
thanks for answering
i wanted just to give a better idea, anyway you were near to get it.
the only difference is that the two cursors are not written in dynamic sql, just like strings, but are real cursors.
anyway, this is the version of the package i need, but i am not able to compile
(your original code is commented and immediately below there is my code)
CREATE OR REPLACE PACKAGE BODY mytest
IS
--cur_a VARCHAR2(200) := 'SELECT dummy FROM DUAL';
CURSOR cur_a
IS
SELECT dummy
FROM DUAL;
--cur_b VARCHAR2(200) := 'SELECT ''fred'' FROM DUAL';
CURSOR cur_b
IS
SELECT 'fred' fred
FROM DUAL;
TYPE t_cur_a IS REF CURSOR
RETURN cur_a%ROWTYPE
--PROCEDURE routine_a_b (p_cur SYS_REFCURSOR) IS
PROCEDURE routine_a_b (p_cur t_cur_a)
IS
v_x VARCHAR2 (10);
BEGIN
LOOP
FETCH p_cur
INTO v_x;
EXIT WHEN p_cur%NOTFOUND;
DBMS_OUTPUT.put_line (v_x);
END LOOP;
END;
PROCEDURE doit
IS
--v_curs SYS_REFCURSOR;
v_curs t_cur_a;
BEGIN
NULL;
-- open v_curs FOR cur_a;
OPEN v_curs FOR cur_a;
routine_a_b (v_curs);
CLOSE v_curs;
-- open v_curs FOR cur_b;
-- routine_a_b(v_curs);
-- close v_curs;
END;
END;
the error is:
cursor 'V_CURS' cannot be used in dynamic SQL OPEN statement
i did read that if use weak ref cursor, it could work, so i declare the ref cursor type in this way:
TYPE t_cur_a IS REF CURSOR;
instead than
TYPE t_cur_a IS REF CURSOR
RETURN cur_a%ROWTYPE
what i get is another error (in the open cursor command)
PLS-00382: expression is of wrong type....
but if i replace
OPEN v_curs FOR cur_a;
with
OPEN v_curs for select dummy from dual;
it works... but i already knew it.. :-)
anyway, i used a work around to resolve it, so it's just philosophy -
Dispalying output from a REF CURSOR
Friends,
I'm getting my self into indepth pl/sql and need some help from you to clear some basic concepts.
create table MASTER_TABLE
street_info varchar2(100),
property_type varchar2(50) ------- i.e values here would be 'HOME_TABLE' ,'COM_PROP_TABLE' etc
create table HOME_TABLE
property_id char(5),
prop_desc varchar2(100),
cost varchar2(10),
location varchar2(100)
create table COM_PROP_TABLE
property_id char(5),
prop_desc varchar2(100),
cost varchar2(10),
location varchar2(100)
I want to use a single procedure to open a weak REF CURSOR variable for the appropriate table based on the street address and display all information from that table.
Here is what I want to to - execute a stored procedure which accepts 1 'in' paramter and 1 'in out ' parameter.
IN paramter - accepts street address
IN OUT paramter - depending on address , if it is related to 'Homes' , it should display all information from the HOME Table, else it will display information from the 'Commerical Property' table.
create or replace package pack_address_info as
type v_info_type ref cursor;
end pack_address_info;
create or replace procedure schema.sp_home_info(v_add in varchar2,v_show in out v_info_type)
is
home_type constant integer :=1;
commercial_type constant integer :=2;
cursor show_data_cur is
select property_type from MASTER TABLE where street_info=v_add;
var_cursor show_data_cur%rowtype;
begin
open show_data_cur;
fetch show_data_cur into var_cursor;
close show_data_cur;
if var_cursor.property_type= HOME_TABLE
then
open v_show for
select * from HOME_TABLE where location=v_add;
elseif var_cursor.table_name = COM_PROP_TABLE
then
open v_show for
select * from COM_PROP_TABLE where location=v_add;
end if;
end schema.sp_home_info;
I can create the package and the stored proc ... but then ???? i'm stuck ;(
Now , i don't know how to display the output from the HOME TABLE or the COM_PROP_TABLE depending on what the address is entered? Is this code correct. Can you please help me modify this code so that I can achieve my objective.
This is an example from the book 'Oracle PL/SQL Programming, 4th Edition' under the 'CURSOR' section - 15.6
Thanks for the help in advance.Here is one sample ->
satyaki>
satyaki>select * from v$version;
BANNER
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - Prod
PL/SQL Release 10.2.0.3.0 - Production
CORE 10.2.0.3.0 Production
TNS for 32-bit Windows: Version 10.2.0.3.0 - Production
NLSRTL Version 10.2.0.3.0 - Production
Elapsed: 00:00:00.02
satyaki>
satyaki>
satyaki>CREATE OR REPLACE PACKAGE aaa_sat
2 AS
3 TYPE crs IS REF CURSOR RETURN emp%ROWTYPE;
4 FUNCTION fc_retcur (e_no IN NUMBER)
5 RETURN crs;
6 END aaa_sat;
7 /
Package created.
Elapsed: 00:00:01.03
satyaki>
satyaki>
satyaki>CREATE OR REPLACE PACKAGE BODY aaa_sat
2 AS
3 FUNCTION fc_retcur (e_no IN NUMBER)
4 RETURN crs
5 IS
6 l_crs crs;
7 BEGIN
8 OPEN l_crs FOR
9 SELECT * FROM emp
10 WHERE empno = e_no;
11
12 RETURN l_crs;
13 END;
14 END aaa_sat;
15 /
Package body created.
Elapsed: 00:00:00.18
satyaki>
satyaki>
satyaki>DECLARE
2 l_emp_rec emp%ROWTYPE;
3 l_crs aaa_sat.crs;
4 BEGIN
5 l_crs := aaa_sat.fc_retcur (7782);
6 LOOP
7 FETCH l_crs
8 INTO l_emp_rec;
9 EXIT WHEN l_crs%NOTFOUND;
10 DBMS_OUTPUT.put_line (l_emp_rec.ename);
11 END LOOP;
12 CLOSE l_crs;
13 END;
14 /
CLARK
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.40
satyaki>
satyaki>Got Me?
Regards.
Satyaki De. -
I have a stored procedure that returns a weak REF CURSOR as an out parameter. I want to access the rows that are returned, in an OCI application. I want a sample OCI program that does this. The PL/SQL code is as follows
PACKAGE TEST_PACKAGE AS
TYPE RCT IS REF CURSOR;
END;
PROCEDURE TEST_PROCEDURE (R OUT TEST_PACKAGE.RCT)
AS
BEGIN
OPEN r FOR
SELECT * FROM XXX;
END;
THANKS.Hello,
I used in my application regular connections, I created
CallableStatement with these connections, later I got one cursor with:
mr = ((OracleCallableStatement)cstmt).getCursor(1)
where mr is ResultSet and cstmt is CallableStatement.
But, when I use the Commerce PoolConnection I get serialConnection
and it creates serialCallableStatement and the command:
mr = ((OracleCallableStatement)cstmt).getCursor(1)
get the next exception:
java.lang.ClassCastException:
weblogic.jdbc20.rmi.SerialCallableStatement at......
Are you working with Bea ConnectionPool
or regular Connections?
Thank you.
<BLOCKQUOTE><font size="1" face="Verdana, Arial">quote:</font><HR>Originally posted by Matt Sivertson ([email protected]):
I'm having a very strange problem with some JDBC code. Basically, there is a StoredProcedure in the DB that we call through JDBC. One of the out parameters is a REF CURSOR. My user does not have select access to the table, but the stored procedure does. When I try and get the ResultSet corresponding to that RefCursor using the OracleCallableStatement.getCursor() method, and exception gets thrown saying it cannot find the table. We checked on the database, and it is actually performing a new select statement as My user, rather than as the StoredProcedure. If we open up the permissions on the table, everything works fine, but this defeats the whole purpose of what the DBA wants.
BTW, this same Stored Procedure works when fine when accesed through PL/SQL or SQL+. Only JDBC seems to have a problem with it. Any help is greatly appreciated.
Matt Sivertson
[email protected]<HR></BLOCKQUOTE>
null -
Stored procedure and ref cursor problem
I am trying to create a stored procedure that can be used in Crystal Reports. To do this I have to create a package and a ref cursor. My SQL is below:
--Package
Create or Replace Package Test_Package
as type test_type is ref cursor;
end;
--Procedure
Create or Replace Procedure Test_Proc
(test_cursor in out test_package.test_type,
parameter in string
as
begin
open test_cursor for
select ClientName from apbpman.cv_client where clientref = parameter;
end;
--When trying to execute the SP in Oracle I use:-
set serveroutput on
declare
test_cursor apbpman.test_package.test_type;
resultset test_cursor%rowtype;
begin
apbpman.test_proc(test_cursor,'0096');
if not test_cursor%isopen then
dbms_output.put_line ('OK');
else
dbms_output.put_line ('Not OK');
end if;
fetch test_cursor into resultset;
while test_cursor%found loop
dbms_output.put_line(resultset.ClientName);
fetch test_cursor into resultset;
end loop;
end;
Whenever this runs I receive the following error reports:
resultset test_cursor%rowtype;
ERROR at line 3:
ORA-06550: line 3, column 13:
PLS-00320: the declaration of the type of this expression is incomplete or malformed
ORA-06550: line 3, column 13:
PL/SQL: Item ignored
ORA-06550: line 11, column 25:
PLS-00320: the declaration of the type of this expression is incomplete or malformed
ORA-06550: line 11, column 2:
PL/SQL: SQL Statement ignored
ORA-06550: line 13, column 24:
PLS-00320: the declaration of the type of this expression is incomplete or malformed
ORA-06550: line 13, column 3:
PL/SQL: Statement ignored
ORA-06550: line 14, column 26:
PLS-00320: the declaration of the type of this expression is incomplete or malformed
ORA-06550: line 14, column 3:
PL/SQL: SQL Statement ignored
I have tried in vain to find a resolution to this but have failed. Please help.
Thanks,
PaulUnless you are running a really old version of Oracle, any weak ref cursor can just be declared SYS_REFCURSOR. Also, you can't use a weak ref cursor for %ROWTYPE. You can test the procedure in SQL*Plus by using it to populate a refcursor variable.
-
Dynamic sql and ref cursors URGENT!!
Hi,
I'm using a long to build a dynamic sql statement. This is limited by about 32k. This is too short for my statement.
The query results in a ref cursor.
Does anyone have an idea to create larger statement or to couple ref cursors, so I can execute the statement a couple of times and as an result I still have one ref cursor.
Example:
/* Determine if project is main project, then select all subprojects */
for i in isMainProject loop
if i.belongstoprojectno is null then
for i in ProjectSubNumbers loop
if ProjectSubNumbers%rowcount=1 then
SqlStatement := InitialStatement || i.projectno;
else
SqlStatement := SqlStatement || PartialStatement || i.projectno;
end if;
end loop;
else
for i in ProjectNumber loop
if ProjectNumber%rowcount=1 then
SqlStatement := InitialStatement || i.projectno;
else
SqlStatement := SqlStatement || PartialStatement || i.projectno;
end if;
end loop;
end if;
end loop;
/* Open ref cursor */
open sql_output for SqlStatement;
Thanks in advance,
Jeroen Muis
KCI Datasystems BV
mailto:[email protected]Example for 'dynamic' ref cursor - dynamic WHERE
(note that Reports need 'static' ref cursor type
for building Report Layout):
1. Stored package
CREATE OR REPLACE PACKAGE report_dynamic IS
TYPE type_ref_cur_sta IS REF CURSOR RETURN dept%ROWTYPE; -- for Report Layout only
TYPE type_ref_cur_dyn IS REF CURSOR;
FUNCTION func_dyn (p_where VARCHAR2) RETURN type_ref_cur_dyn;
END;
CREATE OR REPLACE PACKAGE BODY report_dynamic IS
FUNCTION func_dyn (p_where VARCHAR2) RETURN type_ref_cur_dyn IS
ref_cur_dyn type_ref_cur_dyn;
BEGIN
OPEN ref_cur_dyn FOR
'SELECT * FROM dept WHERE ' | | NVL (p_where, '1 = 1');
RETURN ref_cur_dyn;
END;
END;
2. Query PL/SQL in Reports
function QR_1RefCurQuery return report_dynamic.type_ref_cur_sta is
begin
return report_dynamic.func_dyn (:p_where);
end;
Regards
Zlatko Sirotic
null
Maybe you are looking for
-
I am having problems downloading apps from the app store, songs from iTunes, etc. everything else works fine, just can't download anything. Any suggestions? Thanks!
-
Hi Guys, When I am clearing a vendor payment using F-04 transaction I am getting the following error. Pls suggest. *Tax code 00 does not appear in any G/L account item* *Message no. FF753* *Diagnosis* *The document entered contains a customer or vend
-
I have a I-Pad which I use to upload my photos whil traveling. I was recently gone for 40 days and ended up with over 5,000 photos. When I am in Events mode, slideshow works fine. But when I switch to Photo mode or view and try to do a slideshow,
-
Can you put your own videos on the new Apple TV?
-
Can I restore iTunes on my computer using my iPhone iTunes?
Can I restore iTunes on my computer using my iPhone iTunes? I messed up the cover art on many albums; they are still correct on my iPhone.