Is it possible to ref cursor(result set) as in parameter to procedure/funct
Hi,
I am getting a resultset/ref cursor from the Java side to the procedure/function as in parameter. Is this possible in oracle 10g.
If yes can body send the links/suggestions describing some examples.
Thanks,
I am getting a resultset/ref cursor from the Java
side to the procedure/function as in parameter. Is
this possible in oracle 10g. It is possible, but it sounds like you have your application design entirely backwards.
A ref cursor is designed to be used to pass a result set from a stored procedure to a client or calling application.
So while you could use a screwdriver to hammer in a nail, you probably would not want to.
Similar Messages
-
Stored procedure that returns a cursor (result set)
Hi,
We have a stored procedure that returns a cursor (result set) but when I compliled it and catalouged (introspected) it in the OBPM I got all the primitive type parameters (either IN or OUT) in the proc call except the cursor type (the result set) which is the out param of the stored proc.
Any pointers please?
ThanksResult set is of RowType and is not supported as a Stored Procedure as far as I know.
HTH
Sharma -
Ref Cursor - how to access through parameter name
Hi,
I'm using the below table and sample data. The below script named 'Script1' works well, my concern is values for the first and second parameters need to be used for the thrid and fourth one as well.
When I try with 'Script2' it gives "ORA-01008: not all variables bound ORA-06512: at line 17" error. I know Paramterized cursor can handle this effecively, since it is a dynamic SQL, I need to use from a parameter table, I don't have any control over the number of parameteters, parameter name, type and other things. So, I cannot go for parameterized cursor.
As of now, for my requirement, Script1 works fine, is there any way to make Script2 to work as well, I need to pass paramters by name, not by position, please give your suggestions, thank you.
CREATE TABLE T1
F1 NUMBER(5),
F2 VARCHAR2(100),
F3 DATE
Insert into T1
(F1, F2, F3)
Values
(1, 'One', TO_DATE('08/02/2012 07:43:34', 'MM/DD/YYYY HH24:MI:SS'));
Insert into T1
(F1, F2, F3)
Values
(2, 'Two', TO_DATE('08/02/2012 08:15:24', 'MM/DD/YYYY HH24:MI:SS'));
Insert into T1
(F1, F2, F3)
Values
(3, 'Three', TO_DATE('08/02/2012 08:16:34', 'MM/DD/YYYY HH24:MI:SS'));
COMMIT;
Script1:
declare
TYPE t_ref_cursor IS REF CURSOR;
v_cursor t_ref_cursor;
v_query_str varchar2(3000);
v_f1 number(5);
v_f2 varchar2(100);
v_f3 date;
begin
v_query_str := 'SELECT f1, f2, f3 from t1 where f1 = :p1 and f3 = to_date(:p2, ''DD-MON-YYYY hh24:mi:ss'') union ';
v_query_str := v_query_str || 'select 1, ''c1'', sysdate from dual where not exists (select 1 from t1 where f1 = :p3 and f3 = to_date(:p4, ''DD-MON-YYYY hh24:mi:ss''))';
--dbms_output.put_line(v_query_str);
open v_cursor for v_query_str using 1, '02-AUG-2012 07:43:34', 1, '02-AUG-2012 07:43:34';
loop
fetch v_cursor into v_f1, v_f2, v_f3;
exit when v_cursor%notfound;
dbms_output.put_line(v_f1 || ' ' || v_f2 || '' || v_f3);
end loop;
dbms_output.put_line('rowcount ' || v_cursor%rowcount);
close v_cursor;
end;
Script2:
declare
TYPE t_ref_cursor IS REF CURSOR;
v_cursor t_ref_cursor;
v_query_str varchar2(3000);
v_f1 number(5);
v_f2 varchar2(100);
v_f3 date;
begin
v_query_str := 'SELECT f1, f2, f3 from t1 where f1 = :p1 and f3 = to_date(:p2, ''DD-MON-YYYY hh24:mi:ss'') union ';
v_query_str := v_query_str || 'select 1, ''c1'', sysdate from dual where not exists (select 1 from t1 where f1 = :p1 and f3 = to_date(:p2, ''DD-MON-YYYY hh24:mi:ss''))';
--dbms_output.put_line(v_query_str);
open v_cursor for v_query_str using 1, '02-AUG-2012 07:43:34';
loop
fetch v_cursor into v_f1, v_f2, v_f3;
exit when v_cursor%notfound;
dbms_output.put_line(v_f1 || ' ' || v_f2 || '' || v_f3);
end loop;
dbms_output.put_line('rowcount ' || v_cursor%rowcount);
close v_cursor;
end;
/This link shall answer your Question. PL/SQL Dynamic SQL.
If it had been an Anonymous Block, your code would work through.
Please see demonstration below:
create or replace procedure emp_data (dep_id number, sal number, emp_id number)
is
l_cnt number;
begin
select count(*)
into l_cnt
from hr.employees
where department_id = dep_id
and salary >= sal
and employee_id > emp_id;
dbms_output.put_line('Count :: ' || l_cnt);
end;
declare
l_cnt number;
begin
execute immediate 'begin emp_data(:1, :2, :2); end;' using 20, 100;
end;
anonymous block completed
Count :: 2
--Trying the Similar example as in your OP.
--Execute the same Select statement as in emp_Data with Bind Variables;
declare
l_cnt number;
begin
--execute immediate 'begin emp_data(:1, :2, :2); end;' using 20, 100;
execute immediate 'select count(*)
from hr.employees
where department_id = :1
and salary >= :2
and employee_id > :2' into l_cnt using 20, 100;
dbms_output.put_line('Count :: ' || l_cnt);
end;
Results in error :- ORA-01008: not all variables bound -
How can I dynamically alter search spec for results set based on parameter
We have defined a string parameter in BIP as p_lastName.
We pass this to our RTF template in $p_lastName, definition in RTF as per below:
<?param@begin:p_lastName;'%'?>
We want to include this data in a table based on our dataset but applying the parameter as a search criteria - in the form of
<?for-each:/DATA/XML/DATA_FEED/row[LAST_NAME= $p_lastName]?>
Our issue arises if user does not enter any value in the $p_lastName. In this way the comparison becomes = '%' which will not return any records.
If there is a LIKE operator in XSL we could use that.
Would appreciate anyones assistance?There is no like, but contains
contains(LAST_NAME,'A') -
Hi ,
I use a REF CURSOR when we want to execute a dynamic select statement causes to retrieve more than one record.
We can pass Ref cursor result as a out parameter which can be used in other subprograms right.
I want to pass a coloumn name and get coloumn values as out parameter.This can be used in other stored procedure.
This is my code.
CREATE OR REPLACE PROCEDURE pasval(pColName IN VARCHAR2, pResultSet OUT SYS_REFCURSOR) IS
l_sql VARCHAR2(2000);
--l_ret SYS_REFCURSOR;
--l_val VARCHAR2(1000);
BEGIN
l_sql := 'SELECT DISTINCT ' || pColName || 'into pResultSet FROM TABLE_NAME' ;
execute immediate l_sql;
end;
I am gettingthe errror like this
ORA-00904: "ACCT_TYPE_CODEINTO": invalid identifier
ORA-06512: at "PMA.PAS_TEST", line 7
ORA-06512: at line 9
ORA-00904: "pcc_type_no": invalid identifier --even though the pcc_type_no is coloumn in table_name Table
Thanks,I still didn't get and remains the same,
How to pass l_sql values into OUT parameter.
CREATE OR REPLACE PROCEDURE pasval(pColName IN VARCHAR2, pResultSet OUT SYS_REFCURSOR) IS
l_sql VARCHAR2(2000);
--l_ret SYS_REFCURSOR;
--l_val VARCHAR2(1000);
BEGIN
l_sql := 'SELECT DISTINCT ' || pColName || 'into pResultSet FROM TABLE_NAME' ;
execute immediate l_sql;
end;
I am gettingthe errror like this
ORA-00904: "PCC_TYPE_NOINTO": invalid identifier
ORA-06512: at "PMA.PAS_TEST", line 7
ORA-06512: at line 9
ORA-00904: "pcc_type_no": invalid identifier --even though the pcc_type_no is coloumn in table_name Table -
Is it possible to pass a ref cursor from java as an input parameter to a stored procedure, which the procedure can then process?
(Passing Ref Cursors as output parameters from a stored procedure to a result set works fine.)You may want to try passing Arrays to the Stored Procedure. Use Oracle.SQL.ARRAY and then in the stored procedure get the array.
-
How to give ref cursor in VB procedure call
This is my Oracle Sp
CREATE OR REPLACE PROCEDURE CRD_DMAN.infy_usp_trades_by_broker_bkr
** Procedure name: CRD_DMAN.USP_TRADES_BY_BROKER
** Author's name: Infosys
** Date written: 04/11/07
** Description: Compliance Trade by Borker
** Maintenance history:
** Date Chg req# Name Remarks
** 04/11/07 Infosys Created
p_ordercursor IN OUT infy_pkg_compliance_transact.cur_compliancetrade,
p_startdate IN VARCHAR,
p_enddate IN VARCHAR,
p_fundcode IN cs_fund_config.parent_acct_cd%TYPE,
p_clientcode IN ts_order_alloc.acct_cd%TYPE,
p_brokercode IN ts_order_alloc.exec_broker%TYPE,
p_reportname IN report_log.report_name%TYPE,
p_callingapplication IN report_log.calling_application%TYPE,
p_callinguser IN report_log.calling_user%TYPE
IS
--Declaring Local Variables
v_owner VARCHAR2 (30);
v_startdate VARCHAR2 (10);
v_enddate VARCHAR2 (10);
v_rowcount NUMBER:=0;
v_logrec base_util_pkg.crd_log_record;
exp_error EXCEPTION;
v_fundcodevalue NUMBER;
BEGIN
BEGIN
/*checking if the start date and end date are null and
assigning the sysdate accordingly*/
IF (TRIM(p_startdate) IS NULL )
THEN
v_startdate := TO_CHAR (SYSDATE, 'mm/dd/yy');
ELSE
v_startdate := p_startdate;
END IF;
IF (TRIM(p_enddate) IS NULL )
THEN
v_enddate := TO_CHAR (SYSDATE, 'mm/dd/yy');
ELSE
v_enddate := p_enddate;
END IF;
/*checking if fund code is null and assigning value accordingly*/
IF TRIM (p_fundcode) IS NULL
THEN
v_fundcodevalue := 0;
ELSE
v_fundcodevalue := 1;
END IF;
/*checking if the reportname or calling user or calling
application name*/
IF (p_reportname IS NULL OR p_callinguser IS NULL
OR p_callingapplication IS NULL)
THEN
RAISE exp_error;
END IF;
END;
--opening and fetching the data into cursor
v_logrec.start_time := SYSDATE;
BEGIN
OPEN p_ordercursor
FOR
SELECT
oa.exec_broker EXEC_BROKER_CODE,
b.bkr_name EXEC_BROKER_NAME,
oa.acct_cd CLIENT_CODE,
f.acct_name CLIENT_NAME,
CASE WHEN (Exists (SELECT 1
FROM cs_fund_broker fb
WHERE rel_typ_cd IN('P','M')
AND oa.exec_broker=fb.BKR_CD
AND oa.acct_cd =fb.acct_cd))
THEN 'Y'
ELSE 'N' END DIRECTED_BROKER,
COUNT ( distinct o.order_id) COUNT_TICKNUM,
MAX (o.trade_date) TRADE_DATE,
SUM (oa.exec_amt) BASE_COST,
SUM (oa.commision_amt) TOTAL_COMMISSION,
(SELECT ab.bkr_typ_cd FROM au_broker ab
WHERE ab.au_change_date =(SELECT TO_TIMESTAMP(MAX(ab.au_change_date))
FROM au_broker ab WHERE b.bkr_typ_cd != ab.bkr_typ_cd AND b.bkr_cd = ab.bkr_cd))
BROKER_HISTORY
FROM
ts_order o
JOIN ts_order_alloc oa ON (o.order_id = oa.order_id)
JOIN cs_broker b ON(oa.exec_broker = b.bkr_cd)
JOIN cs_fund f ON(oa.acct_cd = f.acct_cd)
WHERE
o.status = 'ACCT'
AND oa.exec_broker = CASE WHEN TRIM (p_brokercode) IS NULL
THEN oa.exec_broker
ELSE TRIM(p_brokercode) END
AND oa.acct_cd = CASE WHEN TRIM(p_clientcode) IS NULL
THEN oa.acct_cd
ELSE TRIM(p_clientcode) END
AND ((0 = v_fundcodevalue) OR EXISTS (SELECT 1 FROM crd.cs_fund_config cf
WHERE cf.parent_acct_cd =TRIM (p_fundcode)
AND oa.acct_cd = cf.child_acct_cd))
AND o.trade_date BETWEEN TO_DATE (v_startdate, 'mm/dd/yy')
AND TO_DATE (v_enddate, 'mm/dd/yy')
GROUP BY oa.exec_broker, b.bkr_name ,oa.acct_cd ,f.acct_name,oa.directed_broker,b.bkr_typ_cd,b.bkr_cd;
END;
BEGIN
SELECT
owner
INTO
v_owner
FROM
all_objects
WHERE
object_name = 'INFY_USP_TRADES_BY_BROKER_BKR';
v_logrec.end_time := SYSDATE;
v_logrec.user_code := v_owner;
v_logrec.input_param_values := 'INFY_USP_TRADES_BY_BROKER_BKR,'
|| v_startdate
|| ','
|| v_enddate
|| ','
|| p_fundcode
|| ','
|| p_clientcode
|| ','
|| p_brokercode;
v_logrec.report_name := p_reportname;
v_logrec.object_name := 'INFY_USP_TRADES_BY_BROKER_BKR';
v_logrec.rows_returned := v_rowcount;
v_logrec.calling_application := p_callingapplication;
v_logrec.calling_user := p_callinguser;
END;
BEGIN
--calling the procedure to insert values into the report_log table
COMMIT;
SET TRANSACTION READ WRITE;
base_util_pkg.crd_base_util_proc (v_logrec);
SET TRANSACTION READ ONLY;
END;
EXCEPTION
WHEN exp_error
THEN
DBMS_OUTPUT.put_line ('ERROR');
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line ('ERROR OCCURED' || SQLCODE);
DBMS_OUTPUT.put_line (SQLERRM);
END infy_usp_trades_by_broker_bkr;
END OF CRD_DMAN.USP_TRADES_BY_BROKER
This is my Pakage from where i am using ref cursor
CREATE OR REPLACE PACKAGE CRD_DMAN.infy_pkg_compliance_transact
AS
** Package name : CRD.INFY_PKG_COMPLIANCE_TRANSACTIONS
** Author's name : Infosys
** Date written : 06/11/07
** Project/System : CRD
** Description : Compliance Trades By Borker Package
** Maintenance history:
** Date Chg req# Name Remarks
** 06/11/07 CRD Infosys Created
--Defining The ComplianceTrade Record DataType
TYPE rec_compliancetrade IS RECORD (
exec_broker_code crd.ts_order_alloc.exec_broker%TYPE,
exec_broker_name crd.cs_broker.bkr_name%TYPE,
client_code crd.ts_order_alloc.acct_cd%TYPE,
client_name crd.cs_fund.acct_name%TYPE,
directed_broker crd.ts_order_alloc.directed_broker%TYPE,
count_ticknum crd.ts_order.order_id%TYPE,
trade_date crd.ts_order.trade_date%TYPE,
base_cost crd.ts_order_alloc.cur_base_mkt_val%TYPE,
total_commission crd.ts_order_alloc.commision_amt%TYPE,
broker_history crd.au_broker.bkr_typ_cd%TYPE
--Declaring a variable of rec_auditdata data type
TYPE cur_compliancetrade IS REF CURSOR
RETURN rec_compliancetrade;
END infy_pkg_compliance_transact;
END OF CRD.INFY_PKG_COMPLIANCE_TRANSACTIONS
How to call this SP from VB code with ref cursor parameter?I'm fairly sure that's not possible, since there's nothing in the ODBC spec to allow for ref cursors. The driver has built in support to check for ref cursors that are returned via a stored procedure call, but there's nothing built into the driver to pass one IN. Since a ref cursor can't be constructed on the client side, you'd have to have some sort of structure that allowed you to reference the ref cursor directly in order to be able to pass one back to the database.
Since you're using VB.NET anyway, the better solution is probably just to use ODP.NET instead, which DOES allow you to reference a ref cursor directly, and there are samples that install with ODP.NET that show you how to do that.
Greg -
Using ref cursor in "in clause" in select statement
Hi,
Is there any way can we use the ref cursor in the in condition of a select statement.
Regards,
Venkat.
Edited by: ramanamadhav on Aug 23, 2011 11:14 AMramanamadhav wrote:
I'm sorry if I post in confusing way. I will give an example. Just see the psudo code here.
declare
rf_cur sys_refcursor;
begin
pr_test(empno,rf_cur);
-- rf_cur returning emp names.
select * from emp
where empname in (ref_cusor results);-- here i want to consume my ref cursor result in the in conditions.
end;
Thanks &Regards,
Venkat.No you can't do that. A ref cursor is not a set of results as you believe.
Take a read of this article...
{thread:id=886365} -
REF Cursor to be called via Reports 6i to display data
Hello Sir/Madam,
I'm new to REF Cursor, so I would appriciate your help..
My requirements are to display records higher then nine records for a given facilityID from the REGSTATVLVS table sorted by vlv_nbr (field)
So far, I have Icreated a package and when I execute this package it is prompting
ERROR at line 1:
ORA-06550: line 1, column 7:
PLS-00306: wrong number or types of arguments in call to 'LSTVLV_REFCUR'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
Note: I can display the data using "rownum", but that is not allowing me to sort it by valve#..
Sorry for redundancy for redency
CREATE OR REPLACE package GFS_ADMIN.vlvlst is
type v_cursor is REF CURSOR return REGSTATVLVS%rowtype;
PROCEDURE lstvlv_refcur(vlvno OUT v_cursor);
end;
CREATE OR REPLACE package body vlvlst is
PROCEDURE lstvlv_refcur(vlvno OUT v_cursor) IS
vlv_num varchar2(1000);
cursor vlv_cur is
select vlv_nbr
from REGSTATVLVS r
where r.fclty_seq_nbr = 83
order by vlv_nbr;
vlv_rcd vlv_cur%rowtype;
begin
if not vlv_cur%isopen then
open vlv_cur;
end if;
<<i_loop>> for i in 1..40 loop
fetch vlv_cur into vlv_rcd;
EXIT WHEN vlv_cur%NOTFOUND;
if ( i <= 9 ) then
vlv_num := vlv_rcd.vlv_nbr;
dbms_output.put_line(vlv_num);
-- dbms_output.put_line(vlv_rcd.vlv_nbr);
end if;
end loop;
end;
end;
variable v1 varchar2(6);
set serveroutput on
set autoprint on
execute vlvlst.lstvlv_refcur(:v1);
Regards,
VaniHello InoL,
REF Cursor is working better if it is a Navigator, Toad or SQLPlus.. but it is prompting all sort of errors when it is used within Reports 6i.. Here is what i was trying to achieve..
The purpose of "REF Cursor" is to retrieve multiple parameter values .. ( at least that is what GOOGLE results were about REF Cursor )..
At the same time, a function does not return more then one value and I'm not sure if Reports will allow to use a stored procedure. So, I started to use REF Cursor
"lstvlv_refcur(vlvno OUT v_cursor )" I'm trying to retrieve as I mentioned 9 valve records to one report and remaining valve records to 2nd report, which I'm calling it via SRW reports built-in package..
Here is the latest and greatest code on my REF Cursor..
1) created "global temporary table" one time..
2) within Reports added this package ( as a program unit )
package vlvlst_chk is
type vlvlst_rcd is RECORD
( fctly_seq_nbr number,
vlv_nbr varchar2(6));
type vlvno_refcur is REF CURSOR return vlvlst_rcd;
end;
3) then added a function called QR_1RefCurDS ( as a program unit )
function QR_1RefCurDS return vlvlst_chk.vlvno_refcur is
hld_vlvlst vlvlst_chk.vlvno_refcur;
fctno INTEGER;
vno varchar2(6);
begin
delete from fct_vlv_hold;
commit;
delete from fct_vlv_hold2;
commit;
open hld_vlvlst for
select r.fclty_seq_nbr,r.vlv_nbr
from REGSTATVLVS r
where r.fclty_seq_nbr = :p_2
order by vlv_nbr;
for i in 1..40 loop
fetch hld_vlvlst into fctno, vno;
exit when hld_vlvlst%notfound;
if i <= 9 then
insert into fct_vlv_hold
values(fctno, vno);
commit;
-- return hld_vlvlst;
elsif (i>9 and i<= 40) then
insert into fct_vlv_hold2
values(fctno, vno);
commit;
-- return hld_vlvlst;
else
return hld_vlvlst;
end if;
end loop;
close hld_vlvlst;
return hld_vlvlst;
end;
Here: prompts "REP-0065/REP-0200" error, but writes records to temp tables..
Question is why is it prompting this error?
Edited by: user11141511 on Jan 24, 2012 1:25 PM
Edited by: user11141511 on Jan 24, 2012 1:27 PM -
How to get the result set in batches
I have a query which results into large data. This data i want to display in a group of 20. After every 20 records i want to add header and footer to it.
Is it possible to get the result set data into batch of 20 ? means can i specify start and end index of query ?
regards
ManishaWhat I am saying is that a big query with lots of
joins will probably be slow, and as such would be a
ripe candidate for batching the responses, if it were
not possible to speed/optimize it. Batching is nice
to look at for the user, but is not a solution for
performance problems. In essence it is irrelevant
that it adds a little performance deficit, as it
appears to be running a lot quicker, and gives more
feedback to the user.Then let me say it again....
- "Join" is a term that applies to a method of doing queries in the database....
- Query 1 which uses a join and returns 15 rows
- Query 2 which does not use a join and returns 1500 rows.
Given the above then Query 1 will provide better overall performance for the system than Query 2 in a properly configured database.
If it doesn't then the database is not set up correctly.
And again this will be irrespective of whether the query is scrollable or not. -
Hi All,
My requirement is to fetch values from any given tables through ref cursor, so i have used a below procedure
CREATE OR REPLACE
PROCEDURE et1(
tab_name IN VARCHAR2,
c1 OUT sys_refcursor)
AS
v_prim_val VARCHAR2(2000);
v_sql VARCHAR2(2000);
BEGIN
SELECT wm_concat(s.column_name)
INTO v_prim_val
FROM user_cons_columns s ,
user_constraints c
WHERE c.constraint_name=s.constraint_name
AND c.constraint_type ='P'
AND s.table_name =tab_name;
dbms_output.put_line('Col val='||v_prim_val);
v_sql:='select '||v_prim_val|| ' from easy where id in (1,2,3)';
OPEN c1 FOR v_sql;
END et1;
/Problem with above code is the record set returned by ref cursor will be unknown so in which variable should i put it in?
below code will create table for above procedure
create table easy(id integer, event_rowid integer,txn_rowid integer,txn_name varchar2(200));
begin
for i in 1..5 loop
insert into easy values(i,'777'||i,i||89,'Ris'||i||i);
end loop;
end;
commit;
alter table easy add constraint pk_easy primary key(id,event_rowid,txn_name);While googling i found "we can't fetch into a variable of the weak cursor's row type." But I don't know the record set or the variables being returned .
Please help!983088 wrote:
Is there alternative for wm_concat?Read the FAQ: {message:id=9360005}
under the string aggregation techniques
Thanks Billy for your reply
I had a requirement and i tried something , apparently it's a fiasco
I understand static sql is the key but not for my Lock.
I have 300 tables in my Database ,I have to fetch primary key and there values on some condition which user will pass .So, you're saying a user should be able to extract any data they want from any table of their choice with any conditions they want? Such 'users' are usually technical administrators who know the database and are trusted not to damage things.
Now please tell me when i don't know which table they will pass and table may have any number of primary keys and if i have used dynamic sql so what's wrong in that?It means that your business requirement is too 'generic' and there is no solid design to what the requirements are.
what approach should i follow?Use the DBMS_SQL package. This allows a 'dynamic' query to be constructed, parsed (and thus validated) and then queried where you can fetch the columns by numeric position (column number 1, column number 2 etc.) as well as determining their datatypes and names etc.
An example from my standard library of examples, where I use DBMS_SQL to take any query and extract the details of that query to output the data returned as a CSV file...
As sys user:
CREATE OR REPLACE DIRECTORY TEST_DIR AS '\tmp\myfiles'
GRANT READ, WRITE ON DIRECTORY TEST_DIR TO myuser
/As myuser:
CREATE OR REPLACE PROCEDURE run_query(p_sql IN VARCHAR2
,p_dir IN VARCHAR2
,p_header_file IN VARCHAR2
,p_data_file IN VARCHAR2 := NULL) IS
v_finaltxt VARCHAR2(4000);
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_fh UTL_FILE.FILE_TYPE;
v_samefile BOOLEAN := (NVL(p_data_file,p_header_file) = p_header_file);
BEGIN
c := DBMS_SQL.OPEN_CURSOR;
DBMS_SQL.PARSE(c, p_sql, DBMS_SQL.NATIVE);
d := DBMS_SQL.EXECUTE(c);
DBMS_SQL.DESCRIBE_COLUMNS(c, col_cnt, rec_tab);
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);
WHEN 2 THEN DBMS_SQL.DEFINE_COLUMN(c,j,v_n_val);
WHEN 12 THEN DBMS_SQL.DEFINE_COLUMN(c,j,v_d_val);
ELSE
DBMS_SQL.DEFINE_COLUMN(c,j,v_v_val,2000);
END CASE;
END LOOP;
-- This part outputs the HEADER
v_fh := UTL_FILE.FOPEN(upper(p_dir),p_header_file,'w',32767);
FOR j in 1..col_cnt
LOOP
v_finaltxt := ltrim(v_finaltxt||','||lower(rec_tab(j).col_name),',');
END LOOP;
-- DBMS_OUTPUT.PUT_LINE(v_finaltxt);
UTL_FILE.PUT_LINE(v_fh, v_finaltxt);
IF NOT v_samefile THEN
UTL_FILE.FCLOSE(v_fh);
END IF;
-- This part outputs the DATA
IF NOT v_samefile THEN
v_fh := UTL_FILE.FOPEN(upper(p_dir),p_data_file,'w',32767);
END IF;
LOOP
v_ret := DBMS_SQL.FETCH_ROWS(c);
EXIT WHEN v_ret = 0;
v_finaltxt := NULL;
FOR j in 1..col_cnt
LOOP
CASE rec_tab(j).col_type
WHEN 1 THEN DBMS_SQL.COLUMN_VALUE(c,j,v_v_val);
v_finaltxt := ltrim(v_finaltxt||',"'||v_v_val||'"',',');
WHEN 2 THEN DBMS_SQL.COLUMN_VALUE(c,j,v_n_val);
v_finaltxt := ltrim(v_finaltxt||','||v_n_val,',');
WHEN 12 THEN DBMS_SQL.COLUMN_VALUE(c,j,v_d_val);
v_finaltxt := ltrim(v_finaltxt||','||to_char(v_d_val,'DD/MM/YYYY HH24:MI:SS'),',');
ELSE
DBMS_SQL.COLUMN_VALUE(c,j,v_v_val);
v_finaltxt := ltrim(v_finaltxt||',"'||v_v_val||'"',',');
END CASE;
END LOOP;
-- DBMS_OUTPUT.PUT_LINE(v_finaltxt);
UTL_FILE.PUT_LINE(v_fh, v_finaltxt);
END LOOP;
UTL_FILE.FCLOSE(v_fh);
DBMS_SQL.CLOSE_CURSOR(c);
END;This allows for the header row and the data to be written to seperate files if required.
e.g.
SQL> exec run_query('select * from emp','TEST_DIR','output.txt');
PL/SQL procedure successfully completed.Output.txt file contains:
empno,ename,job,mgr,hiredate,sal,comm,deptno
7369,"SMITH","CLERK",7902,17/12/1980 00:00:00,800,,20
7499,"ALLEN","SALESMAN",7698,20/02/1981 00:00:00,1600,300,30
7521,"WARD","SALESMAN",7698,22/02/1981 00:00:00,1250,500,30
7566,"JONES","MANAGER",7839,02/04/1981 00:00:00,2975,,20
7654,"MARTIN","SALESMAN",7698,28/09/1981 00:00:00,1250,1400,30
7698,"BLAKE","MANAGER",7839,01/05/1981 00:00:00,2850,,30
7782,"CLARK","MANAGER",7839,09/06/1981 00:00:00,2450,,10
7788,"SCOTT","ANALYST",7566,19/04/1987 00:00:00,3000,,20
7839,"KING","PRESIDENT",,17/11/1981 00:00:00,5000,,10
7844,"TURNER","SALESMAN",7698,08/09/1981 00:00:00,1500,0,30
7876,"ADAMS","CLERK",7788,23/05/1987 00:00:00,1100,,20
7900,"JAMES","CLERK",7698,03/12/1981 00:00:00,950,,30
7902,"FORD","ANALYST",7566,03/12/1981 00:00:00,3000,,20
7934,"MILLER","CLERK",7782,23/01/1982 00:00:00,1300,,10-----
Billy ,BTW u made my day i was just telling my girlfriend i got a reply from Oracle Ace, THXSmall things please .... -
Want to manipulate the ref cursor
Hi,
iam having a procedure whiuch returns a ref cursor as a output parameter having 20 columns.
i had to manipulate only 2 columns in that ref cursor output in another calling procedure.
iam getting an error when iam fetching the ref cursor result into only 2 variables.
How can i achieve this ?Why?
Let's see it ->
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.18
satyaki>
satyaki>create or replace procedure r_gen_arg(
2 choice in number,
3 b in out sys_refcursor
4 )
5 is
6 str varchar2(500);
7 begin
8 if choice = 1 then
9 str := 'select * from emp';
10 elsif choice = 2 then
11 str := 'select * from dept';
12 end if;
13
14 open b for str;
15 exception
16 when others then
17 dbms_output.put_line(sqlerrm);
18 end;
19 /
Procedure created.
Elapsed: 00:00:04.51
satyaki>
satyaki>
satyaki>declare
2 rec_x emp%rowtype;
3 rec_y dept%rowtype;
4 w sys_refcursor;
5 begin
6 dbms_output.enable(1000000);
7 r_gen_arg(1,w);
8 loop
9 fetch w into rec_x;
10 exit when w%notfound;
11 dbms_output.put_line('Employee No: '||rec_x.empno||' - '||
12 'Name: '||rec_x.ename||' - '||
13 'Job: '||rec_x.job||' - '||
14 'Manager: '||rec_x.mgr||' - '||
15 'Joining Date: '||rec_x.hiredate||' - '||
16 'Salary: '||rec_x.sal||' - '||
17 'Commission: '||rec_x.comm||' - '||
18 'Department No: '||rec_x.deptno);
19 end loop;
20 close w;
21
22 r_gen_arg(2,w);
23 loop
24 fetch w into rec_y;
25 exit when w%notfound;
26 dbms_output.put_line('Department No: '||rec_y.deptno||' - '||
27 'Name: '||rec_y.dname||' - '||
28 'Location: '||rec_y.loc);
29 end loop;
30 close w;
31 exception
32 when others then
33 dbms_output.put_line(sqlerrm);
34 end;
35 /
Employee No: 9999 - Name: SATYAKI - Job: SLS - Manager: 7698 - Joining Date: 02-NOV-08 - Salary: 55000 - Commission: 3455 - Department No: 10
Employee No: 7777 - Name: SOURAV - Job: SLS - Manager: - Joining Date: 14-SEP-08 - Salary: 45000 - Commission: 3400 - Department No: 10
Employee No: 7521 - Name: WARD - Job: SALESMAN - Manager: 7698 - Joining Date: 22-FEB-81 - Salary: 1250 - Commission: 500 - Department No: 30
Employee No: 7566 - Name: JONES - Job: MANAGER - Manager: 7839 - Joining Date: 02-APR-81 - Salary: 2975 - Commission: - Department No: 20
Employee No: 7654 - Name: MARTIN - Job: SALESMAN - Manager: 7698 - Joining Date: 28-SEP-81 - Salary: 1250 - Commission: 1400 - Department No: 30
Employee No: 7698 - Name: BLAKE - Job: MANAGER - Manager: 7839 - Joining Date: 01-MAY-81 - Salary: 2850 - Commission: - Department No: 30
Employee No: 7782 - Name: CLARK - Job: MANAGER - Manager: 7839 - Joining Date: 09-JUN-81 - Salary: 4450 - Commission: - Department No: 10
Employee No: 7788 - Name: SCOTT - Job: ANALYST - Manager: 7566 - Joining Date: 19-APR-87 - Salary: 3000 - Commission: - Department No: 20
Employee No: 7839 - Name: KING - Job: PRESIDENT - Manager: - Joining Date: 17-NOV-81 - Salary: 7000 - Commission: - Department No: 10
Employee No: 7844 - Name: TURNER - Job: SALESMAN - Manager: 7698 - Joining Date: 08-SEP-81 - Salary: 1500 - Commission: 0 - Department No: 30
Employee No: 7876 - Name: ADAMS - Job: CLERK - Manager: 7788 - Joining Date: 23-MAY-87 - Salary: 1100 - Commission: - Department No: 20
Employee No: 7900 - Name: JAMES - Job: CLERK - Manager: 7698 - Joining Date: 03-DEC-81 - Salary: 950 - Commission: - Department No: 30
Employee No: 7902 - Name: FORD - Job: ANALYST - Manager: 7566 - Joining Date: 03-DEC-81 - Salary: 3000 - Commission: - Department No: 20
Department No: 10 - Name: ACCOUNTING - Location: NEW YORK
Department No: 20 - Name: RESEARCH - Location: DALLAS
Department No: 30 - Name: SALES - Location: CHICAGO
Department No: 40 - Name: LOGISTICS - Location: CHICAGO
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.85
satyaki>
satyaki>Here, i don't have to use separate variable to hold those required value.
Regards.
Satyaki De. -
Is there any way in Raptor to view the content of a REF CURSOR being passed OUT from a stored procedure?
In SQL PLUS, I'll do this:
SET LINESIZE 1000;
SET PAGESIZE 1000;
VAR X REFCURSOR;
BEGIN
MY_USP(:X);
END;
PRINT X;
Is there a Raptor equivalent?Actually, I didn't just vote for the request, I'm the only one who did ;-P
Some bug in the APEX stuff that still says I'm MATT MATT instead of the updated MRM (Mútua ReddisMATT).
Also seriously, I have no problems as to the order of things getting implemented (that's why you've got management for).
I understand that a feature with only two requests is low prio, especially if it's a tough one.
The only thing I don't like are veto's. If you don't like to implement a feature, you can mark it as low prio, waiting for comunity votes, etc. (you know it can stay in such states forever). Rejecting something is really not a nice thing to do, but hey, what can we do about it...
Regards,
K. -
JDBC Result Set from Non-Database Source
In Java, is it possible to create a result set from a non-database data source?, for example an XML file, text file, vectors, java beans
We have a Swing application that currently makes direct JDBC calls to the DB2 database for creating result sets. We want to replace JDBC calls with calls to web service, but want to still create result sets on the client, so the replacement of the datasource from database to web service call is transparent to the rest of the code.In Java, is it possible to create a result set from a
non-database data source?, Yes.
for example an XML file,
text file, vectors, java beans
We have a Swing application that currently makes
direct JDBC calls to the DB2 database for creating
result sets. We want to replace JDBC calls with calls
to web service, but want to still create result sets
on the client, so the replacement of the datasource
from database to web service call is transparent to
the rest of the code.You might want to think carefully about what you are doing.
It is fairly easy, although somewhat tedious (many methods,) to create a new type of ResultSet.
But if the above application is doing SQL via statements and expecting the result via a ResultSet then you are not just creating a ResultSet but an entire driver and one that will have to deal with SQL as well. And if you have to handle the SQL itself that means you will probably need a parser and interpreter. -
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
Maybe you are looking for
-
Error Message when starting up Dreamweaver
So the other day, my Dreamweaver 8 started acting up. When opened, I got a Javascript error message on my dwscriptsExtData.js file. Basically the only thing I noticed was that I wasn't able to paste anything on dreamweaver, and several of the button
-
To restrict authorization of tcode MEK1,MEK2,MEK3,MEK4 at plant level
Hi, We have a requirement where we need to restrict authorization for tcode MEK1,MEK2,MEK3,MEK4 at plant level. Presently we can restrict authorization at Purchasing organization level but not at Plant level. Any pointer please! Regards, Chetan
-
My Photoshop CS3 wont open help!!!
Even though its old I still use PS3 and I went to open it and this window pops up with a white box and no text that I was unable to close (only the yellow dot option to minimize) It says on the top "Adobe Photoshop CS3 Extended" and in the photoshop
-
Hi, Just to make sure I didn't miss something. It seems that newer versions of Adobe Reader with separate FlashPlayer plugin deny playing zero size (i. e. not consuming document page space) RMAs anymore. In case of short auto-played sound RMAs, the u
-
Why am I getting this code when trying to watch Youtube Videos?
I have been doing research and nothing shows up... I am not an html 5 user on Youtube either so its not that.