Ref cursors - 'with' clause
I am working with a procedure which is returning a ref-cursor to a Java Call. Inside the procedure I see a statment like
Open t_results for
with rfq_companies AS
select statement1),
rfq_hierarchies AS
select statement2),
rfq_relnhierarchies AS
select statement 3);
Can anybody explain such an usage for opening a ref cursor ('WITH' clause)?. What is the effect of using this and how Java will interpret this?
The procedure is still returning a REF CURSOR, regardless of the way the SELECT statements is created. There is no effect as far as Java is concerned.
Read more on the WITH clause:
http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/statements_10002.htm#sthref9697
in the section: Subquery Factoring
Similar Messages
-
Difference Ref cursor with/with out using clause
Hi everyone,
When I am using dynamic sql with USING clause ,the results are not sorted in Ascending order.
DECLARE
TYPE emp_refcursor IS REF CURSOR;
emp_rc emp_refcursor;
TYPE v_emp_id IS TABLE OF number INDEX BY PLS_INTEGER;
TYPE v_last_name IS TABLE OF varchar2(50) INDEX BY binary_integer;
V_empno v_emp_id;
v_ename v_last_name;
p_deptno number := &U_DEPTNO;
v_limit number := 10;
v_ordcolumn varchar2(20) := 'employee_id';
v_stmt varchar2(1000);
BEGIN
v_stmt :=
'select employee_id,last_name from employees
where department_id = :x order by :y ';
dbms_output.put_line(v_stmt);
OPEN emp_rc FOR v_stmt USING p_deptno,v_ordcolumn;
LOOP
FETCH emp_rc BULK COLLECT INTO v_empno,v_ename LIMIT v_limit;
EXIT WHEN v_empno.count = 0;
FOR I IN v_empno.first .. v_empno.last
LOOP
dbms_output.put_line(v_empno(i)||' '||v_ename(i));
END LOOP;
END LOOP;
END;
When I use dynamic sql with out USING cluase,results are sorted in Ascending order.
DECLARE
TYPE emp_refcursor IS REF CURSOR;
emp_rc emp_refcursor;
TYPE v_emp_id IS TABLE OF number INDEX BY PLS_INTEGER;
TYPE v_last_name IS TABLE OF varchar2(50) INDEX BY binary_integer;
V_empno v_emp_id;
v_ename v_last_name;
p_deptno number := &U_DEPTNO;
v_limit number := 10;
v_ordcolumn varchar2(20) := 'employee_id';
v_stmt varchar2(1000);
BEGIN
v_stmt :=
'select employee_id,last_name from employees
where department_id = '||p_deptno ||
' order by '||v_ordcolumn;
dbms_output.put_line(v_stmt);
OPEN emp_rc FOR v_stmt;
LOOP
FETCH emp_rc BULK COLLECT INTO v_empno,v_ename LIMIT v_limit;
EXIT WHEN v_empno.count = 0;
FOR I IN v_empno.first .. v_empno.last
LOOP
dbms_output.put_line(v_empno(i)||' '||v_ename(i));
END LOOP;
END LOOP;
END;
P.S :---- department_id (used) = 50;
Please can some one explain why this is happening like this.
Thanks
Raghu
--------------------------------------------------------------------------------Hi sundar,
I am new to oracle and learning/trying to get the same output by using differnt methods,rather than using FOR LOOP ,I tried to use ref cursor with dynamic sql.I am in a belief that ref cursor's with dynamic sql are faster than FOR LOOP,irrespective of the size of data.Can you correct me if I am wrong.
Coming back to ur reply,how should my statement look like,when using ref cursor
with USING claus to sort data by asc/desc order.
Thanks in advance
Raghu -
Dynamic REF Cursor with Dynamic Fetch - Urgent
i have a pl/sql package with generates dynamic SQL statments. my problem is i want to open this SQL statment dynamically and fetch data in dynamic variable.
declare
type type_temp is REF CURSOR;
cur_temp type_temp;
mv_sql varchar2(4000);
begin
-- this will be dunamically generated and
-- hence could have any no. of columns.
mv_sql := select f1, f2, f3, f4 from table_temp;
open cur_temp for mv_sql;
fetch cur_temp into c1, c2, c3, c4;
close cur_temp;
end;
problem is my sql statment will have N no. of columns how can i fetch this N no. of columns.Very hard problem, because ref cursors do not (directly) support description!
Se mine (non-ideal) solution (it may be doable, but it isn't very practical
or easily maintainable):
1. "Generic" package
CREATE OR REPLACE PACKAGE dyn_fetch IS
TYPE ref_cur_t IS REF CURSOR;
g_query VARCHAR2 (32000);
g_count NUMBER;
g_desc_tab DBMS_SQL.DESC_TAB;
varchar2_type CONSTANT PLS_INTEGER := 1;
number_type CONSTANT PLS_INTEGER := 2;
date_type CONSTANT PLS_INTEGER := 12;
rowid_type CONSTANT PLS_INTEGER := 11;
char_type CONSTANT PLS_INTEGER := 96;
long_type CONSTANT PLS_INTEGER := 8;
raw_type CONSTANT PLS_INTEGER := 23;
mlslabel_type CONSTANT PLS_INTEGER := 106;
clob_type CONSTANT PLS_INTEGER := 112;
blob_type CONSTANT PLS_INTEGER := 113;
bfile_type CONSTANT PLS_INTEGER := 114;
PROCEDURE describe_columns;
FUNCTION record_def RETURN VARCHAR2;
END;
CREATE OR REPLACE PACKAGE BODY dyn_fetch IS
PROCEDURE describe_columns IS
l_cur INTEGER;
BEGIN
l_cur := DBMS_SQL.OPEN_CURSOR;
DBMS_SQL.PARSE (l_cur, g_query, DBMS_SQL.NATIVE);
DBMS_SQL.DESCRIBE_COLUMNS (l_cur, g_count, g_desc_tab);
DBMS_SQL.CLOSE_CURSOR (l_cur);
EXCEPTION
WHEN OTHERS THEN
IF DBMS_SQL.IS_OPEN (l_cur) THEN
DBMS_SQL.CLOSE_CURSOR (l_cur);
END IF;
RAISE;
END;
FUNCTION record_def RETURN VARCHAR2 IS
l_record_def VARCHAR2 (32000);
l_type VARCHAR2 (100);
l_col_type PLS_INTEGER;
l_col_max_len PLS_INTEGER;
l_col_precision PLS_INTEGER;
l_col_scale PLS_INTEGER;
BEGIN
FOR i IN 1..g_count LOOP
l_col_type := g_desc_tab(i).col_type;
l_col_max_len := g_desc_tab(i).col_max_len;
l_col_precision := g_desc_tab(i).col_precision;
l_col_scale := g_desc_tab(i).col_scale;
IF l_col_type = varchar2_type THEN
l_type := 'VARCHAR2(' || l_col_max_len || ')';
ELSIF l_col_type = number_type THEN
l_type := 'NUMBER(' || l_col_precision || ',' || l_col_scale || ')';
ELSIF l_col_type = date_type THEN
l_type := 'DATE';
ELSIF l_col_type = rowid_type THEN
l_type := 'ROWID';
ELSIF l_col_type = char_type THEN
l_type := 'CHAR(' || l_col_max_len || ')';
-- ELSIF l_col_type = ...
-- long_type, raw_type ...
END IF;
l_record_def := l_record_def || ' col_' || i || ' ' || l_type || ',';
END LOOP;
l_record_def := RTRIM (l_record_def, ',');
RETURN l_record_def;
END;
END;
Note that procedure "record_def" creates columns names as col_1 (col_2 ...)
because SELECT clause in your query can be without aliases, for example
"SELECT deptno || dname FROM dept".
2. Your package which returns query nad ref cursor
CREATE OR REPLACE PACKAGE test IS
PROCEDURE set_query (p_query VARCHAR2 := NULL);
FUNCTION ref_cur RETURN dyn_fetch.ref_cur_t;
END;
CREATE OR REPLACE PACKAGE BODY test IS
PROCEDURE set_query (p_query VARCHAR2 := NULL) IS
l_query VARCHAR2 (32000) :=
' SELECT e.empno, e.ename,' ||
' e.deptno, d.dname' ||
' FROM emp e,' ||
' dept d' ||
' WHERE e.deptno = d.deptno';
BEGIN
IF p_query IS NULL THEN
dyn_fetch.g_query := l_query;
ELSE
dyn_fetch.g_query := p_query;
END IF;
END;
FUNCTION ref_cur RETURN dyn_fetch.ref_cur_t IS
l_ref_cur dyn_fetch.ref_cur_t;
BEGIN
OPEN l_ref_cur FOR dyn_fetch.g_query;
RETURN l_ref_cur;
END;
END;
Why we need two separate procedures (functions) in your package ?
a) Receiving program must use dynamic SQL, but in dynamic block we can access
only PL/SQL code elements that have global scope (standalone functions and procedures,
and elements defined in the specification of a package).
Unfortunately, cursor variables cannot be defined in the specification of a package
(cannot be global variables).
b) Receiving program must get the column list before ref cursor.
So, we have two options: call (in receiving program) the same function two times
(once to get the column list and once to return a ref cursor)
or use one procedure (or function) for returning query (to get the column list)
and second function for returning a ref cursor.
3. Your receiving program
CREATE OR REPLACE PROCEDURE test_fetch_ref_cur (p_query VARCHAR2 := NULL) IS
l_statement VARCHAR2 (32000);
FUNCTION process_def RETURN VARCHAR2 IS
l_process_def VARCHAR2 (32000);
BEGIN
l_process_def := 'DBMS_OUTPUT.PUT_LINE (';
FOR i IN 1 .. dyn_fetch.g_count LOOP
l_process_def := l_process_def || ' l_record.col_' || i || ' || ''>>'' || ';
END LOOP;
l_process_def := RTRIM (l_process_def, ' || ''>>'' || ') || ');';
RETURN l_process_def;
END;
BEGIN
test.set_query (p_query);
dyn_fetch.describe_columns;
l_statement :=
' DECLARE' ||
' TYPE record_t IS RECORD (' ||
dyn_fetch.record_def || ');' ||
' l_record record_t;' ||
' l_ref_cur dyn_fetch.ref_cur_t;' ||
' BEGIN' ||
' l_ref_cur := test.ref_cur;' ||
' LOOP' ||
' FETCH l_ref_cur INTO l_record;' ||
' EXIT WHEN l_ref_cur%NOTFOUND;' ||
process_def ||
' END LOOP;' ||
' CLOSE l_ref_cur;' ||
' END;';
EXECUTE IMMEDIATE l_statement;
END;
You can test this with:
SET SERVEROUTPUT ON;
EXECUTE test_fetch_ref_cur;
Note that we can try to use more generic solution:
CREATE OR REPLACE PACKAGE dyn_fetch IS
-- SAME AS BEFORE, PLUS:
PROCEDURE fetch_ref_cur (
p_function_ref_cur VARCHAR2,
p_process_def VARCHAR2);
END;
CREATE OR REPLACE PACKAGE BODY dyn_fetch IS
-- SAME AS BEFORE, PLUS:
PROCEDURE fetch_ref_cur (
p_function_ref_cur VARCHAR2,
p_process_def VARCHAR2)
IS
l_statement VARCHAR2 (32000);
BEGIN
l_statement :=
' DECLARE' ||
' TYPE record_t IS RECORD (' ||
record_def || ');' ||
' l_record record_t;' ||
' l_ref_cur dyn_fetch.ref_cur_t;' ||
' BEGIN' ||
' l_ref_cur := ' ||
p_function_ref_cur || ';' ||
' LOOP' ||
' FETCH l_ref_cur INTO l_record;' ||
' EXIT WHEN l_ref_cur%NOTFOUND;' ||
p_process_def ||
' END LOOP;' ||
' CLOSE l_ref_cur;' ||
' END;';
EXECUTE IMMEDIATE l_statement;
END;
END;
CREATE OR REPLACE PROCEDURE test_fetch_ref_cur (p_query VARCHAR2 := NULL) IS
FUNCTION process_def RETURN VARCHAR2 IS
-- SAME AS BEFORE
END;
BEGIN
test.set_query (p_query);
dyn_fetch.describe_columns;
dyn_fetch.fetch_ref_cur (
p_function_ref_cur => 'test.ref_cur',
p_process_def => process_def);
END;
Regards,
Zlatko Sirotic -
REF cursor with special characters
Hi all,
I want to display the record set using ref cursor. I am passing varchar field as parameter. How to give this in where cluase of select statement.
i want to use like %parameter_name% in where condition. How to use it in ref cursor.
Thanks in advance,
Paluser546710 wrote:
Hi all,
I want to display the record set using ref cursor. I am passing varchar field as parameter. How to give this in where cluase of select statement.
i want to use like %parameter_name% in where condition. How to use it in ref cursor.
Thanks in advance,
PalWhy using a ref cursor? Do you understand the purpose of ref cursors and how to use them?
Perhaps take a read of the following to get to grips with the basics...
PL/SQL 101 : Understanding Ref Cursors
PL/SQL 101 : Understanding Ref Cursors -
How to use REF cursor with toplink
Hi,
I have a stored proc has a out variable which is a REF CURSOR.
How to read my cursor with toplink?I have got it. Here is the solution.
UnitOfWork uow= dbSession.acquireUnitOfWork();
StoredProcedureCall call = new StoredProcedureCall();
call.setProcedureName("smart.getCompanyStruct");
call.addNamedArgument("xnrid");
call.useNamedCursorOutputAsResultSet("cpy");
DataReadQuery query = new DataReadQuery();
query.setCall(call);
Vector parameters = new Vector();
query.addArgument("xnrid");
parameters.add(new Long(5009L));
Vector obj = (Vector) uow.executeQuery(query, parameters);
Vector contains result ser of the cursor
Gurcan -
Dynamic Ref Cursor with Dynamic Fetch
Hi,
I'm using dynamic sql (DBMS_SQL) to define columns of ref cursor.
It works Ok but the problem is when i'm using PL/SQL CURSOR in the REF CURSOR. Then,
I'm getting :
Error at line 3
ORA-00932: inconsistent datatypes: expected NUMBER got CURSER
ORA-06512: at "SYS.DBMS_SQL", line 1830
ORA-06512: at "TW.PRINT_REF_CURSOR", line 28
ORA-06512: at line 9
Here is my code:
set serveroutput on
exec DBMS_OUTPUT.ENABLE(1000000);
declare
l_cursor sys_refcursor;
begin
OPEN l_cursor FOR
SELECT SERVICE_TABLE.SERVICE, SERVICE_TABLE.SERVICE_GROUP, SERVICE_TABLE.SERVICE_DESC,
CURSOR(SELECT SERVICE_TABLE.SERVICE_CD FROM SERVICE_TABLE) SERVICE_CD_CURSOR
FROM SERVICE_TABLE ;
print_ref_cursor( l_cursor );
end;
=========================
CREATE OR REPLACE procedure print_ref_cursor
( p_query in out sys_refcursor,
p_date_fmt in varchar2 default 'dd-mon-yyyy hh24:mi:ss' )
is
l_theCursor integer;
l_columnValue varchar2(4000);
l_descTbl dbms_sql.desc_tab2;
l_colCnt number;
l_date date;
l_cursor SYS_REFCURSOR;
begin
l_theCursor := dbms_sql.to_cursor_number( p_query );
dbms_sql.describe_columns2
( l_theCursor, l_colCnt, l_descTbl );
-- define all columns to be cast to varchar2's, we
-- are just printing them out
for i in 1 .. l_colCnt loop
if ( l_descTbl(i).col_type in ( 12, 178, 179, 180, 181, 231 ) )
then
dbms_sql.define_column
(l_theCursor, i, l_date );
else
dbms_sql.define_column
(l_theCursor, i, l_columnValue, 4000);
end if;
end loop;
while ( dbms_sql.fetch_rows(l_theCursor) > 0 )
loop
for i in 1 .. l_colCnt loop
if ( l_descTbl(i).col_type in ( 12, 178, 179, 180, 181, 231 ) )
then
dbms_sql.column_value( l_theCursor, i, l_date );
l_columnValue := to_char( l_date, p_date_fmt );
else
dbms_sql.column_value( l_theCursor, i, l_columnValue );
end if;
dbms_output.put_line
( rpad( l_descTbl(i).col_schema_name || '.' ||
l_descTbl(i).col_name, 30 ) || ': ' || l_columnValue );
end loop;
dbms_output.put_line( '-----------------' );
end loop;
dbms_sql.close_cursor( l_theCursor );
end;
Is there a solution or bypass?
Regards,
Tamir GevaNo. The problem is that one cannot use DBMS_SQL.define_column() to define that column in the SQL projection as a cursor, and then use DBMS_SQL.column_value() to read it into a ref cursor variable.
You can however detect the cursor column - the DBMS_SQL.describe_columns3() call will return a col_type value of 102. In which case you can treat it as an exception (i.e. not process that column in the projection).
As a general issue - a cursor as a SQL column projection does not make sense to me. I have never used this in any production code. Nor do I see any reasons why.
If you want that column in the projection to contain a "list" of sorts (the results of the cursor), then a nested table type can be used as projected type and the MultiSet() function used to execute the in-line SQL and provide that SQL cursor's result as an array/nested table.
But even this approach raises the question why a standard relational join is not used? -
How to create a procedure to output REF CURSOR with any WHERE clause?
I have an requirement like this: I have huge query which need to reuse in my code more than 10 times. This SQL has about 50 lines. Thing is for those 10 odd times sometimes the WHERE clause changes (columns are the same). So I cannot create a view since SQL is not static.
I thought of writing a procedure with a WHERE_CLAUSE input para. I output a sys refcursor by adding the where clause. But I can't do it since you cannot add a where clause like that.
i.e.
PROCEDURE dynamyic_query (p_where_clause IN VARCHAR2, p_out_query OUT SYS_REFCURSOR ) IS
BEGIN
OPEN p_out_query FOR SELECT ......... FROM table WHERE || ' ' || p_where_clause;
END;The above gives error.
How to handle a situation like this???? Any help would be greatly appreciated.I tried this method:
I created a table tab_test which has these records:
TNAME TABTYPE CLUSTERID
ABS_V4_P_ERROR_MESSAGES TABLE
ABS_V4_P_ORG_PARAM TABLE
ABS_V4_P_PARAMETER TABLE
ABS_V4_P_SYS_PARAM TABLE
ACCINTERFACE_PARAMETERS TABLE
ACCOUNTS TABLE
ACCOUNT_EXTRACT_PERIODS TABLE
ACCOUNT_EXTRACT_PERIODS# TABLE
ACCOUNT_EXTRACT_PERIODS_1 TABLE Now I create this proc:
PROCEDURE FORMS_TEXT_DYN_SQL_TEST(p_where_cluase IN VARCHAR2, p_out_cursor OUT SYS_REFCURSOR) IS
v_stmt VARCHAR2(1000);
BEGIN
v_stmt := 'SELECT tname FROM tab_test WHERE tname LIKE ''%ABS_V4%'' AND tabtype = :x';
OPEN p_out_cursor FOR v_stmt using p_where_cluase;
END;I create this code block and run it:
declare
v_tname varchar2(200);
out_cursor sys_refcursor;
begin
forms_text_dyn_sql_test('TABLE', out_cursor );
LOOP
fetch out_cursor INTO v_tname;
exit when out_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(v_tname);
END LOOP;
end;
/I get correct output:
ABS_V4_P_ERROR_MESSAGES
ABS_V4_P_ORG_PARAM
ABS_V4_P_PARAMETER
ABS_V4_P_SYS_PARAMHowever, when I change the proc like this:
PROCEDURE FORMS_TEXT_DYN_SQL_TEST(p_where_cluase IN VARCHAR2, p_out_cursor OUT SYS_REFCURSOR) IS
v_stmt VARCHAR2(1000);
BEGIN
v_stmt := 'SELECT tname FROM tab_test WHERE tname LIKE ''%ABS_V4%'' AND :y';
OPEN p_out_cursor FOR v_stmt using p_where_cluase;
END;And run this code block:
declare
v_tname varchar2(200);
out_cursor sys_refcursor;
begin
forms_text_dyn_sql_test(' 1 = 1 ', out_cursor );
LOOP
fetch out_cursor INTO v_tname;
exit when out_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(v_tname);
END LOOP;
end;
/I get error:
[1]: (Error): ORA-00920: invalid relational operator ORA-06512: at "ABS.FORMS_TEXT_DYN_SQL_TEST", line 6 ORA-06512: at line 5Looks like you can only put column_name = :z, column_name = :y type values. You cannot it seems replace it with any WHERE CLAUSE???? -
Cursor with clause not fetching / retrieving any rows, happens very rarely
Hi Experts,
Applications: Oracle Apps 11.5.10.2
Data base version: 11.2.0.1.0
we are running concurrent programs (scheduled every day), we obsereved one of cursor is not fetching any records (happens rarely);
cursor looks
CURSOR LCU_GET_ADJ_JN_CAT_DET IS WITH LCU_GET_ROWS_DETAILS AS(
-- followed by select ( ) --
--ending with
SELECT *
FROM (SELECT ROW_DET.* FROM LCU_GET_ROWS_DETAILS ROW_DET),
(SELECT COUNT(1) TOTAL_RECORDS,
SUM(ENTERED_DR) TOTAL_CLOSING_DEBIT,
SUM(ENTERED_CR) TOTAL_CLOSING_CREDIT
FROM LCU_GET_ROWS_DETAILS ROW_SUM)
we need total_records, total_closing_debit & total_closing_credit.
please suggest..This how the cursor looks like;
CURSOR LCU_GET_ADJ_JN_CAT_DET IS WITH LCU_GET_ROWS_DETAILS AS(
SELECT <columns1>
FROM (SELECT <columns2> from table1 <conditions>
GROUP BY
UNION ALL
SELECT <columns3> from table2 <conditions>
GROUP BY )
WHERE (columns1_1 <> 0 OR columns1_2 <> 0)
GROUP BY )
SELECT *
FROM (SELECT ROW_DET.* FROM LCU_GET_ROWS_DETAILS ROW_DET),
(SELECT COUNT(1) TOTAL_RECORDS,
SUM(columns1_1) TOTAL_CLOSING_DEBIT,
SUM(columns1_2) TOTAL_CLOSING_CREDIT
FROM LCU_GET_ROWS_DETAILS ROW_SUM)
ORDER BY NATURAL_ACCOUNT, BRANCH_CODE, TRANS_CURRENCY; -
Hi all,
I have a pkg as below and its err message in compile:
create or replace PACKAGE PKG_DARTS1 is
TYPE TY_PARTY_DETAIL1 IS RECORD (
PTY_TYPE xxx.yyyy%TYPE
TYPE cur_partydetail1 IS REF CURSOR RETURN TY_PARTY_DETAIL1;
procedure SP_GetPartyDetail1( c_partydetail1 OUT pkg_darts1.cur_partydetail1) ;
end PKG_DARTS1;
create or replace PACKAGE BODY PKG_DARTS1 as
procedure SP_GetPartyDetail1( c_partydetail1 OUT pkg_darts1.cur_partydetail1)
AS
sql_stmt VARCHAR2(2000);
BEGIN
sql_stmt := 'select ''XXX'' FROM DUAL ';
OPEN c_partydetail1 FOR sql_stmt;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line(sqlerrm);
END SP_GetPartyDetail1;
END PKG_DARTS1;
.Warning: Package Body created with compilation errors.
Errors for PACKAGE BODY PKG_DARTS1:
LINE/COL ERROR
13/3 PL/SQL: Statement ignored
13/8 PLS-00455: cursor 'C_PARTYDETAIL1' cannot be used in dynamic SQL
OPEN statement
what's wrong with my syntax? anything I should care in constructing sql in ref cursor?
thx,
beanYou can't use strongly types ref cursors with dynamic SQL, you will have to use weakly typed.
Hth
Martin -
Hi,
I need to use ref cursors in bpel.
Basically calling a stored proc using DB Adapter , which returns a Ref cursor.
Not able to get it work, any suggestion help is greatly appreciated.
Also followed: http://download.oracle.com/docs/cd/B31017_01/integrate.1013/b28994/adptr_db.htm#CHDDDDJI
But its quite abstract.
Thanks !!Hi Raj,
I am able to use the REF cursor with BPEL.
I am able to pass the resultset from Database using a REF cursor to a BPEL variable .
When you create a BPEL variable , create it with message type as the output message type of the REF Cursor.
Regards
Pradosh -
I am trying to build a report based on Ref Cursor query with dynamic string as given below.
OPEN loc_ref_cur_ugss_pay_car FOR 'SELECT name, email_id, job, remarks FROM employee_desc' ;
On compile I am getting following error.
Encountered the symbol "SELECT....." when expecting one of the following: select.
Can't I use ref cursor with dynamic string?
Thanks & regards,
RakeshIf I will use Select statement without quote then it will be a static query. I want to use the dynamic one which will use different table names depending upon condition. The tables which are to be used here are temparary tables and will be be created through report only.
-
For debugging purposes, I would like to be able to describe a REF CURSOR returned by a function in a package, using pl/sql.
Can you help me ?ZlatKo
A brave attempt and well done for putting up with the forum software.
Alas, I can't catually run the code - I get the following error-stack. I'll have another go at it this lunchtime.
If I'm not mistaken your procedure would give us a visual output of the REF CURSOR structure, just like DESC. I think the original poster was after something they could use programmatically inside a PL/SQL procedure to interrogate and process a REF CURSOR with an unknown signature. It would be possible to walk the structure as you do, suck out the values and store them in arrays. Fine. But without knowing the column names how do we know what to do with these values?
At some point the receiving program has to know what the purpose of the REF CURSOR. We can imagine a function that generates a REF CURSOR from one of three queries depending upon the value of an input parameter. Every program which calls that function must pass in that parameter and therefore must know the signature of the REF CURSOR that it gets back.
The idea of a function returning data at its own whim is a bit laughable. Even web services, surely the ultimate expression of the encapsulation paradigm, insist on the publication of a signature - what we have to put in, what we will get back.
Cheers, APC -
Ref cursor to another Ref cursor.
Actually I have a ref cursor in a package x which has a procedure y.
y has 4 parameters like procedure(a,b,c,d in out ref cursor type)
I have another standalone procedure which has a ref cursor as out parameter and a,b,c as other parameters.
This stand alone procedure implicitly calls the package procedure as x.y(a,b,c,d) d is a ref cursor defined in the stand alone procedure which is populated by the package's y procedure.
My issue is that how to populate the standalone procedure's ref cursor with the value of the package's procedure's ref cursor with out using a temporary table?
Please help me in this regard. It is urgent.Actually I have a ref cursor in a package x which has a procedure y.
y has 4 parameters like procedure(a,b,c,d in out ref cursor type)
I have another standalone procedure which has a ref cursor as out parameter and a,b,c as other parameters.
This stand alone procedure implicitly calls the package procedure as x.y(a,b,c,d) d is a ref cursor defined in the stand alone procedure which is populated by the package's y procedure.
My issue is that how to populate the standalone procedure's ref cursor with the value of the package's procedure's ref cursor with out using a temporary table?
Please help me in this regard. It is urgent. -
Ref cursor argument in where clause
Env: ORCL 9.2
I have a func that uses the parameters in a where clause and returns a ref cursor as result. That works fine.
I want to create an overloaded func that replaces one argument with a ref cursor. (instead of accepting a single value as an argument I want to accept multiple values) Can you specify the ref cursor in a where clause with out looping through the cursor ?
CURRENT
func(arg1,arg2,arg3) returns ref cursor
is
select blah from sometable s
where s.a = arg1
and s.b = arg2
and s.c = arg3
NEW
func(ref_cur_arg1,arg2,arg3) returns ref cursor
is
select blah from sometable s
where s.a = ref_cur_arg1
and s.b = arg2
and s.c = arg3
is there something like:
where s.a in (loop fetch ref_cur_arg1 end loop)
thxThanks Rich,
That's pretty much what I came up with:
FUNCTION f_bond_price_w_bb_stat (
p_id_ref gtyp_instr_id_ref,
p_price_srce bond_price.PRICE_SRCE%type,
p_price_type bond_price.PRICE_TYPE%type,
p_price_date bond_price.PRICE_DATE%type)
RETURN gtyp_bondprice_w_bb_stat_rfc
IS
lv_bondprice_rfc gtyp_bondprice_w_bb_stat_rfc;
TYPE ARRAY1 IS TABLE OF instr_ext_id_map.ext_id_value%TYPE INDEX BY BINARY_INTEGER;
t_instr_id ARRAY1;
instr_ids INSTR_EXT_ID_T := INSTR_EXT_ID_T();
BEGIN
--suck the contents of the ref cursor into a local virtual tmp table
FETCH p_id_ref BULK COLLECT INTO t_instr_id;
FOR i IN 1..t_instr_id.COUNT LOOP
instr_ids.extend;
instr_ids(instr_ids.count) := t_instr_id(i);
END LOOP;
CLOSE p_id_ref;
OPEN lv_bondprice_rfc FOR
SELECT
bs.ID_ISIN,
bs.TICKER,
bs.CPN,
bs.MATURITY,
round(months_between(bs.MATURITY,sysdate)/12,1),
bs.ISSUER_INDUSTRY,
bs.INDUSTRY_SECTOR,
FROM bond_price b,
instr_ext_id_map ext,
etl.mdy_ratingstatic mrs,
etl.mdy_extid mxid,
etl.bloomberg_static bs
WHERE b.INSTR_ID = ext.instr_id
AND bs.ID_ISIN(+) = ext.ext_id_value
AND bs.ID_ISIN = mxid.EXTIDVALUE(+)
AND mrs.MOODYDEBTNUM(+) = mxid.MOODYDEBTNUM
AND ext.ext_id_value in (select * from TABLE (cast (instr_ids AS INSTR_EXT_ID_T) ))
AND b.PRICE_SRCE = p_price_srce
AND b.PRICE_TYPE = p_price_type
AND b.PRICE_DATE = p_price_date
RETURN lv_bondprice_rfc;
END f_bond_price_w_bb_stat; -
Hi,
i got problem when i tried to execute this
declare
cursor c1 is
select distinct code_sdi, code_sdi_p, code_ana
from plan_rules
where code_cpe in (var.whr) and ana_from_flag='Y';
begin
open c1;
loop
fetch c1 into :PLAN_RULES.code_sdi, :PLAN_RULES.code_sdi_p, :PLAN_RULES.code_ana;
exit when c1%notfound;
next_record;
end loop;
close c1;
end;
problem is the clause in with variable var.whr (is declared in program entity as varchar2)..when i insert the same text that is stored in var.whr it works but with the variable it does not..
pls helpClearly, SQL does not consider
WHERE empno IN (p_empno_list)
to be equivalent to
WHERE empno IN (7369,7499,7839,7902)
Think, if you had a value such as 'Salerno è la più bella citta del mondo' that represented a single address line(var.whr)
You create a scalar collection type like this: (sure, other approch you could use)
(this is example for number)
CREATE TYPE INTEGER_TT AS TABLE OF INTEGER
CREATE TYPE VARCHAR2_TT AS TABLE OF VARCHAR2(4000);
DECLARE
p_empno_list CONSTANT INTEGER_TT := INTEGER_TT(7369,7499,7839,7902);
DECLARE
p_empno_list CONSTANT INTEGER_TT := INTEGER_TT(7369,7499,7839,7902);
BEGIN
FOR r IN (
SELECT empno, ename4
FROM emp
WHERE empno IN
( SELECT column_value5
FROM TABLE(p_empno_list) )
LOOP
DBMS_OUTPUT.PUT_LINE(RPAD(r.empno,9) || r.ename);
END LOOP;
END;Regards
Other option could be Dinamyc-SQL and REF-CURSOR
Message was edited by:
RV
Maybe you are looking for
-
How to add MenuBar and MenuItems in JSP Form
Help Me, Dear Forum, I am user of jDeveloper 10g working on JSP (Web Module).So How to add MenuBar and Menu Item, in Our jsp Form.What this type control exist? regards javed khan
-
I have tried everything to get the program to see my printer. By reinstalling divice drivers for printer to reinstalling program several times. Still I can print from my printer but not scan. Any help would be appreciated.
-
Settings For a SIM card in a Security Camera to send emails of the photos
I have a Scoutguard SG880MK-8M security camera. It uses GPRS to send emails of photos to any email address. Or it can send MMS of the photos to a mobile number. It works with a vodafone card installed using the MMS function. I haven't managed to g
-
How do I reference a library of functions saved in an external .js file from within an xdp. The manual says there is something called folder level or user-level scripts in %user profile%/application data. How do I call those files once they are in th
-
Statistical table, pool table, structure, and ordinary table
请教在ABAP引用表时,不同类型的表的区别: statistical table pool table structure, ordinary table 其它 table (请列出) 谢谢!