Sys_refcursor
hi experts,
can you check it script not working
CREATE OR REPLACE PROCEDURE PR_P1(P_DIA NUMBER,P_REV OUT SYS_REFCURSOR)
IS
BEGIN
OPEN P_REV FOR SELECT CODE FROM t WHERE IID=P_DIA;
END;
script:
========
SET SERVEROUTPUT ON
DECLARE
V_REV SYS_REFCURSOR;
BEGIN
PR_P1(P_DIA =>865351534968,P_REV =>V_REV);
DBMS_OUTPUT.PUT_LINE(V_REV);
END;
983376 wrote:
hi experts,
can you check it script not working"Not working" is not an Oracle error. When you have a problem it's always a good idea to post what the error is.
It's also a good idea to read the error yourself and see what it says...
SQL> ed
Wrote file afiedt.buf
1 CREATE OR REPLACE PROCEDURE PR_P1(P_DIA NUMBER,P_REV OUT SYS_REFCURSOR) IS
2 BEGIN
3 OPEN P_REV FOR SELECT ename FROM emp WHERE empno = p_dia;
4* END;
SQL> /
Procedure created.
SQL> set serverout on
SQL> ed
Wrote file afiedt.buf
1 declare
2 v_rev sys_refcursor;
3 begin
4 pr_p1(p_dia => 7788, p_rev => v_rev);
5 dbms_output.put_line(v_rev);
6* end;
SQL> /
dbms_output.put_line(v_rev);
ERROR at line 5:
ORA-06550: line 5, column 3:
PLS-00306: wrong number or types of arguments in call to 'PUT_LINE'
ORA-06550: line 5, column 3:
PL/SQL: Statement ignoredHere, it's quite clear that the error is telling us that the call the PUT_LINE is expecting something different from what you've passed it.
A quick check of the documentation for the DBMS_OUTPUT package, PUT_LINE procedure:
http://docs.oracle.com/cd/E11882_01/appdev.112/e25788/d_output.htm#i1000105
... clearly shows that the procedure only expects to get a VARCHAR2 value as it's input.
Compare that to your own code, and you can see you are passing it a SYS_REFCURSOR rather than VARCHAR2.
Similar Messages
-
Is there any provision to view the selected record using SYS_REFCURSOR?
hi friends ,
I was using SQL Server . now i am shifting to Oracle . so we are changing the Stored Procedures in SQLServer to Oracle SP's. I have given the structure of procedure given below . If possible , i want to see the output of select statement in the TOAD editor . If any body knows please help me
CREATE OR REPLACE PROCEDURE PS_AON
P_STATUS OUT VARCHAR2,
P_CUR OUT SYS_REFCURSOR
AS
BEGIN
OPEN P_CUR FOR
select colum1,column2,column3 from Table 1;
EXCEPTION
WHEN OTHERS THEN
P_STATUS:=SQLERRM;
END;
This is one of the model of stored procedures i am using . And the editor i am using is TOAD 7.3.0 and oracle 9i. Is there any provision to view the selected records by running this procedure in TOAD editor
thanks & regards(assuming you have relatively recent version of TOAD).
Write a small block to call the procedure (or use Toad's 'execute procedure' option) as in the example below. Note the ':' in front of 'v_cur_out'. When you run the block, TOAD will prompt you for a value / datatype for 'v_cur_out'. Ignore the value, set the datatype to 'Cursor' and click OK. The resultset (if any) will be displayed in the Data Grid window below.
DECLARE
v_status VARCHAR2 (32767);
BEGIN
ps_aon (v_status, :v_cur_out);
DBMS_OUTPUT.PUT_LINE ('v_status => ' || v_status);
END;
/ -
CURSOR_ALREADY_OPEN and SYS_REFCURSOR
Hi,
I have noticed that you can open a sys_refcursor without closing it. A co-worker did it in a function and I complained it was not good practice and it would raise an error, but he told me I was wrong. I have tested it and it has worked, so I have lost the argument.
And then I found nothing on Oracle literature about it. Did I miss something? Is it common knowledge?
Thanks, RogerAnd then I found nothing on Oracle literature about it. Did I miss something? Is it common knowledge? It is documented behaviour: Opening a Cursor Variable:
You need not close a cursor variable before reopening it. Note that consecutive OPENs of a static cursor raise the predefined exception CURSOR_ALREADY_OPEN. When you reopen a cursor variable for a different query, the previous query is lost.
« -
Calling a stored procedure with RAW and SYS_REFCURSOR
How do you call a stored procedure with the following input and output parameters?
create or replace PROCEDURE test
v_col1 IN NUMBER DEFAULT NULL ,
v_col2 IN VARCHAR2 DEFAULT NULL ,
v_col3 IN RAW DEFAULT NULL ,
v_vol4 IN DATE DEFAULT NULL,
cv_1 IN OUT SYS_REFCURSOR
OPEN cv_1 FOR
SELECT
lv_tmp1 aaaa ,
lv_tmp2 bbbb,
lv_tmp3 cccc
FROM DUAL ;
END;
Edited by: 925963 on Apr 6, 2012 10:50 AMDid you try just declaring the vars?
untested
declare
myCur SYS_REFCURSOR;
myRaw RAW(4);
BEGIN
test (0, 0, myRaw, sysdate, myCur);
END; -
How to use SYS_REFCURSOR as a table in calling sp
hi gurus,
here i have 2 sp in which i m calling GET_OPREF inside GET_REFCALL. and in GET_REFCAL i want to use output cursou as a table .
plz help me ....
CREATE OR REPLACE PROCEDURE GET_OPREF
(p_cursor OUT SYS_REFCURSOR )
is
begin
open p_cursor FOR
select 10 amt from dual union all
select 20 amt from dual union all
select 30 amt from dual ;
end GET_OPREF ;
CREATE OR REPLACE PROCEDURE GET_REFCALL
is
c_cursor SYS_REFCURSOR ;
r_emp get_2%rowtype ;
v_tot int ;
begin
GET_OPREF(c_Cursor);
select sum (amt) into v_tot from c_Cursor; -- *here i want to user cursor as a table*
dbms_output.put_line(v_tot );
end get_refcall ;Edited by: user12108669 on Dec 1, 2009 5:03 AM
Edited by: user12108669 on Dec 1, 2009 5:09 AMAfter you run the procedure your cursor is open. You can fetch it right away and use it like you would use a regular cursor.
SQL> set serveroutput on
SQL> CREATE OR REPLACE PACKAGE type_pack AS
2 type t_cur is ref cursor;
3 type t_tab is table of number;
4 END type_pack;
5 /
Package created.
SQL> CREATE OR REPLACE procedure test_ref(cur_output out sys_refcursor) i
2 begin
3 open cur_output for
4 with test as
5 (select 1 num from dual
6 union select 2 num from dual
7 union select 3 num from dual)
8 select num
9 from test;
10 end;
11 /
Procedure created.
SQL> CREATE OR REPLACE procedure run_test is
2 cur_test sys_refcursor;
3 tab_cur type_pack.t_tab;
4 begin
5 dbms_output.put_line('running...');
6 test_ref(cur_test);
7 fetch cur_test bulk collect
8 into tab_cur;
9 for i in 1 .. tab_cur.count
10 loop
11 dbms_output.put_line(tab_cur(i));
12 end loop;
13 end;
14 /
Procedure created.
SQL> exec run_test;
running...
1
2
3
PL/SQL procedure successfully completed.
SQL> -
SYS_REFCURSOR takes more time than direct query execution
I have a stored proc which has 4 inputs and 10 output and all outputs are sys_refcursor type.
Among 10 ouputs, 1 cursor returns 4k+ records and all other cursors has 3 or 4 records and average 5 columns in each cursors. For this, it takes 8 sec to complete the execution. If we directly query, it gives output in .025 sec.
I verified code located the issue with cursor which returns 4k+ only.
The cursor opening from a temporary table (which has 4k+ records ) without any filter. The query which inserted into temporary is direct inserts only and i found nothing to modify there.
Can anyone suggest, how we can bring the results in less than 3 sec? This is really a challenge since the code needs to go live next week.
Any help appreciated.
Thanks
RenjishI've just repeated the test in SQL*Plus on my test database.
Both the ref cursor and direct SQL took 4.75 seconds.
However, that time is not the time to execute the SQL statement, but the time it took SQL*Plus in my command window to print out the 3999 rows of results.
SQL> create or replace PROCEDURE TEST_PROC (O_OUTPUT OUT SYS_REFCURSOR) is
2 BEGIN
3 OPEN O_OUTPUT FOR
4 select 11 plan_num, 22 loc_num, 'aaa' loc_nm from dual connect by level < 4000;
5 end;
6 /
Procedure created.
SQL> set timing on
SQL> set linesize 1000
SQL> set serverout on
SQL> var o_output refcursor;
SQL> exec test_proc(:o_output);
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.04
SQL> print o_output;
PLAN_NUM LOC_NUM LOC
11 22 aaa
11 22 aaa
11 22 aaa
11 22 aaa
11 22 aaa
3999 rows selected.
Elapsed: 00:00:04.75
SQL> select 11 plan_num, 22 loc_num, 'aaa' loc_nm from dual connect by level < 4000;
PLAN_NUM LOC_NUM LOC
11 22 aaa
11 22 aaa
11 22 aaa
11 22 aaa
11 22 aaa
11 22 aaa
3999 rows selected.
Elapsed: 00:00:04.75
That's the result I expect to see, both taking the same amount of time to do the same thing.
Please demonstrate how you are running it and getting different results. -
Open sys_refcursor for select from table variable?
Hi,
I've got a challenge for you! :-)
I've got a procedure that has a lot of logic to determine what data should be loaded into a table variable. Because of various application constraints, i can not create a global temporary table. Instead, i'd like to create a table variable and populate it with stuff as i go through the procedure.
The end result of the procedure is that i must be able to pass the results back as a sys_refcursor. This is a requirement that is beyond my control as well.
Is there a way to make this sort of procedure work?
Create Or Replace Procedure Xtst
Mu_Cur In Out Sys_Refcursor
Is
Type Xdmlrectype Is Record (Col1 Varchar2(66));
Type Xdmltype Is Table Of Xdmlrectype;
Rtn Xdmltype;
Begin
Select Internal_Id Bulk Collect Into Rtn From Zc_State;
open mu_cur for select col1 from table(rtn);
end;
11/42 PLS-00642: local collection types not allowed in SQL statements
11/36 PL/SQL: ORA-22905: cannot access rows from a non-nested table item
11/19 PL/SQL: SQL Statement ignored
Show Errors;Not anything i'd want to personally implement.
But for educational purposes only of course....
create table this_will_be_gross
column1 number,
column2 varchar2(30)
insert into this_will_be_gross values (1, 'begin the ugliness');
insert into this_will_be_gross values (2, 'end the ugliness');
variable x refcursor;
ME_XE?
declare
Rtn sys.ODCIVARCHAR2LIST;
BEGIN
SELECT
column1 || '-' || column2 Bulk Collect
INTO
Rtn
FROM
this_will_be_gross;
OPEN :x FOR
SELECT
regexp_substr (column_value, '[^-]+', 1, 1) as column1,
regexp_substr (column_value, '[^-]+', 1, 2) as column2
FROM TABLE(CAST(rtn AS sys.ODCIVARCHAR2LIST));
end;
17 /
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.09
ME_XE?
ME_XE?print :x
COLUMN1 COLUMN2
1 begin the ugliness
2 end the ugliness
2 rows selected.
Elapsed: 00:00:00.11In the above example i 'knew' that a hypen was a safe character to use to break up my data elements (as it would not be found anywhere in the data itself).
I would strongly encourage you not to implement something like this. I realize it's tempting when you are working in strict environments where it can take a serious battle to get structures like temporary tables or SQL Types created, but that's really the proper approach to be taking. -
Issue with sys_refcursor in oracle 10.2.0.4.0
hi,
java is front end application and they want result set to be returned from oracle plsql, for simplicity i am writing code something like below.
create or replace function fun () retrun sys_refcursor is
tablename_cur sys_Refcursor;
begin
open tablename_cur for select statement;
return tablename_cur ;
end;
its all looks good.. but my client IT person questioned me about not closing cursor..
i feel it is good way of doing, not closing this type of cursor variable is fine i.e. tablename_cur in this case, does it cause any issues otherwise.. since i am about write not less 300+ such functions and would like to know on this if this is right practice or would it cuase any increase of opened cursor and never closed,.... therafter any performance issues..
or any other good practive to perform the same task. .. please suggest..
thanks in advance...knowledgespring wrote:
I assume once sys_Refcursor returned all the rows it get closed automatically... i.e. fetched all the rows from it closes the sys_refcursor.. otherwise provide info.
according to you, does it mean if they close result set they use in java would result close of sys_refcursor!!.. not before.. may be somthing like
ResultSet rs = call oracle function which uses sys_refcursor
rs.close --> does it close sys_refcursor .. (would it open till then??!!!)..
java developers says we call functions written in oracle... and resultset to be returned.. (They are different team)..I don't know java, but it's correct, the consumer of the cursor is responsible for closing it.
e.g.
SQL> ed
Wrote file afiedt.buf
1 create or replace function test_rc return sys_refcursor is
2 v_rc sys_refcursor;
3 begin
4 open v_rc for 'select * from emp';
5 return v_rc;
6* end;
SQL> /
Function created.
SQL> var x refcursor;
SQL> exec :x := test_rc();
PL/SQL procedure successfully completed.
SQL> print x;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
7369 SMITH CLERK 7902 17/12/1980 800 20
7499 ALLEN SALESMAN 7698 20/02/1981 1600 300 30
7521 WARD SALESMAN 7698 22/02/1981 1250 500 30
7566 JONES MANAGER 7839 02/04/1981 2975 20
7654 MARTIN SALESMAN 7698 28/09/1981 1250 1400 30
7698 BLAKE MANAGER 7839 01/05/1981 2850 30
7782 CLARK MANAGER 7839 09/06/1981 2450 10
7788 SCOTT ANALYST 7566 19/04/1987 3000 20
7839 KING PRESIDENT 17/11/1981 5000 10
7844 TURNER SALESMAN 7698 08/09/1981 1500 0 30
7876 ADAMS CLERK 7788 23/05/1987 1100 20
7900 JAMES CLERK 7698 03/12/1981 950 30
7902 FORD ANALYST 7566 03/12/1981 3000 20
7934 MILLER CLERK 7782 23/01/1982 1300 10
14 rows selected.Here, the "print" command of SQL*Plus uses the returned ref cursor to fetch the data back from the database, and when it's done it (behind the scenes) closes the cursor.
Oracle can't keep track (or even possibly know) of whether a client consumer of a ref cursor has finished fetching the records. Just because all the records may have been fetched, the cursor itself remains open until closed as it contains information about the state of the cursor e.g. whether there is more data to fetch or not.
{thread:id=886365} -
How to view SYS_REFCURSOR output parameters in TOAD
Hi Team,
Here is my procedure which was compiled succesfully...
procedure SLA_FAILURE_PR_SR(
startdate_i IN DATE,
enddate_i IN DATE,
pacifictimezone_i IN VARCHAR2,
extranet_user_i IN VARCHAR2,
severity_i IN NUMBER,
reportRC_o out sys_refcursor
IS
BEGIN
logpkg.info ('Begin ramOpsReportSummaryPkg.SLA_FAILURE_PR_SR');
open reportRC_o for
SELECT
customer "Client",
case_id_ "Case ID",
to_char(aradmin.datepkg.unixTimeToDate(create_time, 'PST', 'Y'),'MM-DD-YYYY HH12:MI:SS PM') "Created",
to_char(aradmin.datepkg.unixTimeToDate(resolved_time, 'PST', 'Y'),'MM-DD-YYYY HH12:MI:SS PM') "Resolved",
total_downtime__min_ "Down Time",
assigned_to_group_ || ' ' || ASSIGNED_TO_INDIVIDUAL_ "Group Assigned",
reason_for_missed_sla "Reason For Miss",
assigned_to_group_ "Group That Missed",
internal_mgmt_summary "Ops Mgmt summary",
follow_up_proactive_actions "Follow-Up Proactive Actions"
FROM aradmin.hpd_helpdesk
WHERE
create_time >= datepkg.dateToUnixTime(TO_DATE(startdate_i,'YYYY-MM-DD'),pacifictimezone_i)
AND create_time < datepkg.dateToUnixTime(TO_DATE(enddate_i,'YYYY-MM-DD')+7,pacifictimezone_i)
AND extranet_user=extranet_user_i
AND severity = severity_i
AND (MET_RESOLUTION_SLA_=0 or MET_CONTACT_SLA_=0);
logpkg.info ('END ramOpsReportSummaryPkg.SLA_FAILURE_PR_SR');
END SLA_FAILURE_PR_SR;
--The query inside cursor is fetching results. but i couldnt get the results when i executed whole procedure.
-- Can anyone help on this and give me the procedure how to execute it in toad. I am using oracle 10g and Toad 9.6 versions.In Toad type:
BEGIN
SLA_FAILURE_PR_SR(
DATE '02-01-2013', -- substitute with proper start date
DATE '02-18-2013', -- substitute with proper end date
'put pacifictimezone_i value',
'put extranet_user_i value',
1, -- substitute with proper severity
:ref_cur
END;
/Click on Execute/Compile Statement (green triangle). Variables dialog will pop-up. Choose variable type - cursor and direction out. Cursor content will be displayed in Data Grid pane (click on it to see results).
SY. -
Regular expression help to solve sys_refcursor for a record
In reference to my thread Question on sys_refcursor with record type , I thought it can be solved differently. That is:
I have a string like '8:1706,1194,1817~1:1217,1613,1215,1250'
I need to do some manipulation using regular expressions and acheive some thing like
select * from <table> where
c1 in (8,1)
and c2 in (1706,1194,1817,1217,1613,1215,1250);Is it possible using regular expressions in a single select statement?Hi,
Clearance 6`- 8`` wrote:
Your understanding is absolutely correct. But unfortunately it did not work Frank.
SQL> SELECT COUNT (*)
2 FROM (SELECT sp.*
3 FROM spml sp, spml_assignment spag
4 WHERE sp.spml_id = spag.spml_id
5 AND spag.class_of_svc_id = 8
6 AND spag.service_type_id IN (1706, 1194, 1817)
7 AND spag.carrier_id = 4445
8 AND NVL (spag.haulage_type_id, -1) = NVL (NULL, -1)
9 AND spag.effdate = TO_DATE ('01/01/2000', 'mm/dd/yyyy')
10 AND spag.unit_id = 5
11 AND sales_org_id = 1
12 UNION ALL
13 SELECT sp.*
14 FROM spml sp, spml_assignment spag
15 WHERE sp.spml_id = spag.spml_id
16 AND spag.class_of_svc_id = 1
17 AND spag.service_type_id IN (1217, 1613, 1215, 1250)
18 AND spag.carrier_id = 4445
19 AND NVL (spag.haulage_type_id, -1) = NVL (NULL, -1)
20 AND spag.effdate = TO_DATE ('01/01/2000', 'mm/dd/yyyy')
21 AND spag.unit_id = 5
22 AND sales_org_id = 1);
COUNT(*)
88
SQL> SELECT COUNT (*)
2 FROM spml sp, spml_assignment spag
3 WHERE sp.spml_id = spag.spml_id
4 AND spag.carrier_id = 4445
5 AND NVL (spag.haulage_type_id, -1) = NVL (NULL, -1)
6 AND spag.effdate = TO_DATE ('01/01/2000', 'mm/dd/yyyy')
7 AND spag.unit_id = 5
8 AND sales_org_id = 1
9 AND REGEXP_LIKE ('8:1706,1194,1817~1:1217,1613,1215,1250',
10 '(^|~)' || spag.class_of_svc_id || ':'
11 )
12 AND REGEXP_LIKE ('8:1706,1194,1817~1:1217,1613,1215,1250',
13 '(:|,)' || spag.service_type_id || '(,|$)'
14 );
COUNT(*)
140
SQL> Edited by: Clearance 6`- 8`` on Aug 11, 2009 8:04 PMJust serving what you ordered!
Originally, you said you were looking for something that produced the same result as
where c1 in (8, 1)
and c2 in (1706, 1194, 1817, 1217, 1613, 1215, 1250)that is, any of the c1s could be paired with any of the c2s.
Now it looks like what you want is
where ( c1 = 8
and c2 IN (1706, 1194, 1817)
or ( c1 = 1
and c2 IN (1217, 1613, 1215, 1250)
)that is, c1=8 and c2=1250 is no good; neither is c1=1 and c2=1706.
In that case, try
WHERE REGEXP_LIKE ( s
, '(^|~)' || c1
|| ':([0-9]+,)*'
|| c2
|| '(,|~|$)'
) -
Output SYS_REFCURSOR when cursor structure is not known
If i have a variable of type "SYS_REFCURSOR".
This cursor will be passed to various procedures which open various recordset for that cursor, with various number of columns in cursor.
How to output cursor all columns?
1. Maybe java will have metadata information for cursor and can output the resultset of cursor. If so, then this is ok to choose this solution. also VbScript is ok, if it can help.
2. Maybe one can create table temporarily based on the cursor. And table objects have meta data in oracle system tables, so i can output all cursor data.
3. Maybe i can use so called try-catch clauses techique to help somehow. For example
Try
fetch cur1 into varchar2_var1, .., varchar2_var5
catch (if error)
try
fetch cur1 into varchar2_var1, .., varchar2_var4
Till we know how many fields there are.
somehow this way to go next4. Maybe execute immediate can help somehow.If you're not in 11g and you at least have some options of structures you want to try and fetch to, you can make use of the rowtype_mismatch exception by catching it and trying to fetch into a different structure until you find it, by nesting PL/SQL begin...exception...end; blocks.
You won't lose rows if you attempt to fetch into the wrong structure.
In the example below I try to fetch into a type with 2 columns and it fails then I attempt again against a 3-column type.
Note that the column type mismatch on implicit conversions will throw other exceptions as ORA-06504 or ORA-01722 for example.
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.4.0
Connected as fsitja
SQL> set serveroutput on
SQL>
SQL> DECLARE
2 cur SYS_REFCURSOR;
3 TYPE t_rec1 IS RECORD(
4 col1 NUMBER,
5 col2 VARCHAR2(100));
6 v_rec1 t_rec1;
7 TYPE t_rec2 IS RECORD(
8 col3 NUMBER,
9 col4 VARCHAR2(100),
10 col5 VARCHAR2(100));
11 v_rec2 t_rec2;
12 BEGIN
13 OPEN cur FOR
14 SELECT 1 col3, 'a' col4, 'b' col5 FROM dual;
15 FETCH cur
16 INTO v_rec1;
17 dbms_output.put_line('REC1.COL1: ' || v_rec1.col1);
18 dbms_output.put_line('REC1.COL2: ' || v_rec1.col2);
19 EXCEPTION
20 WHEN rowtype_mismatch THEN
21 FETCH cur
22 INTO v_rec2;
23 dbms_output.put_line('REC2.COL3: ' || v_rec2.col3);
24 dbms_output.put_line('REC2.COL4: ' || v_rec2.col4);
25 dbms_output.put_line('REC2.COL5: ' || v_rec2.col5);
26 END;
27 /
REC2.COL3: 1
REC2.COL4: a
REC2.COL5: b
PL/SQL procedure successfully completed
SQL> -
Stored procedure returning multiple records without using SYS_REFCURSOR
Hello,
I am new to oracle stored procedures, have done stored procs in SQL server in past. I am trying to write single stored proc which will return multiple records. I have the stored proc as below and that is compiled without any errors.
We don't want to use SYS_REFCURSOR as output param b'coz the place from which this proc is gonna call, that system doesn't support SYS_REFCURSOR param.
create or replace
PROCEDURE p_get5500DATA_MB (
IN_plan_ID IN T_5500DATA_QWP.Plan_ID%TYPE,
IN_plan_ID_col OUT T_5500DATA_QWP.Plan_ID%TYPE,
p_SEQNUM OUT T_5500DATA_QWP.SEQNUM%TYPE,
p_HEADER_CD OUT T_5500DATA_QWP.HEADER_CD%TYPE,
p_VALUE1 OUT T_5500DATA_QWP.VALUE1%TYPE,
p_VALUE2 OUT T_5500DATA_QWP.VALUE2%TYPE
) AS
BEGIN
SELECT
Plan_ID,
SEQNUM,
HEADER_CD,
VALUE1,
VALUE2
INTO
IN_plan_ID_col,
p_SEQNUM,
p_HEADER_CD,
p_VALUE1,
p_VALUE2
FROM TRS1DBO.T_5500DATA_QWP
WHERE Plan_ID = IN_plan_ID
ORDER BY SeqNum;
-- EXCEPTION
-- WHEN OTHERS THEN
-- RAISE_APPLICATION_ERROR(-210001, 'Error in fetching data from T_5500DATA_QWP....');
END;
Error:
ORA-01422: exact fetch returns more than requested number of rows
ORA-06512: at "TRS1DBO.P_GET5500DATA_MB", line 10
ORA-06512: at line 11
My questions is:
- What would be the best practice for this type of simple stored procedures?
- Is there any alternate or is there anything i can fix in above stored proc which return multiple records?
Thank you,
VimalJust out of curiosity, what are you using for API or driver that doesn't support a ref cursor? Ref cursors are pretty much the defacto standard for passing multiple records out of an Oracle procedure. Oracle's ODP.NET, OLEDB, ODBC, JDBC, OCI, all support ref cursors. Chances are that if the driver you're using doesn't support something as basic/fundamental as a ref cursor, it's probably also not going to support something else either.
You'll most likely want to check with the driver/api vendor on their recommended approach. -
Using CASE statement in Procedure, SYS_REFCURSOR as OUT parameter
Hi all,
What is the mistake in this procedure
create or replace procedure ConditionalSelect( param1 number, refCur IN OUT SYS_REFCURSOR ) is
begin
case
when param1 = 1 then open refCur for select * from AA;
when param1 = 2 then open refCur for select * from EMPLOYEE;
end;
end;
The error i am getting is
Error
[row:1,col:1] ORA-24344: success with compilation error
[row:8,col:5] PLS-00103: Encountered the symbol ";" when expecting one of the following:
case
The symbol "case" was substituted for ";" to continue.
Thanks in advance
pala. you are missing an "end case;"
b. in select - use case only with end - in pl/sql you shulde use "end case"
like "end loop", "end if"
c. case is much more easy to read then a bunch of if's and else if's and else.
Amiel. -
Using SYS_REFCURSOR returned from function in a WHERE clause
Hi All,
I have a plsql function that returns a SYS_REFCURSOR. Typically it will be three columns wide and 1 or more rows. I'd like to use it like:
SELECT *
FROM schema_name.table_name a
WHERE a.date_col BETWEEN trunc(add_months(SYSDATE,-12),'month') AND sysdate
AND ((a.col_a, a.col_b, a.col_c) IN (
open SYS_REFCURSOR returned by schema_name.package_name.function_name('x','y','z')
I've tried casting it to a table, but it complains about an invalid relational operator:
SELECT *
FROM schema_name.table_name a
WHERE a.date_col BETWEEN trunc(add_months(SYSDATE,-12),'month') AND sysdate
AND ((a.col_a, a.col_b, a.col_c) IN (TABLE(schema_name.package_name.function_name('x','y','z')))
Any suggestions would be appreciated!
Thanks,
ThomasRegarding 3360's xml functionality:
SQL> create or replace function f
2 return sys_refcursor
3 as
4 c sys_refcursor;
5 begin
6 open c for
7 select 7788 empno, 'SCOTT' ename from dual
8 union all
9 select 7900 empno, 'JAMES' ename from dual;
10
11 return c;
12 end f;
13 /
Function created.
SQL> select empno, ename
2 from emp
3 where (empno, ename) in
4 (select extractvalue (column_value, 'ROW/EMPNO'),
5 extractvalue (column_value, 'ROW/ENAME')
6 from table (xmlsequence (f)));
EMPNO ENAME
7788 SCOTT
7900 JAMES -
Accessing a returned SYS_REFCURSOR
Hi,
i have a problem accessing records in a weak sys_refcursor (that was returned from another function) inside a PL/SQL function. I alwys get a "PLS-00487: Invalid reference to variable 'REC2'" where rec2 is my loop record variable.
Here is a simplified test which shows the same behaviour (the problem is marked in master_report):
TYPE resType AS OBJECT (
c1 VARCHAR2(80),
c2 VARCHAR2(80),
c3 VARCHAR2(80)
TYPE resTable AS TABLE OF resType;
CREATE OR REPLACE FUNCTION REPORT_01 (uId PLS_INTEGER)
RETURN SYS_REFCURSOR
IS
st_cursor SYS_REFCURSOR;
BEGIN
-- Do various things, builds a dynamic sql query based in input parameters
OPEN st_cursor FOR 'SELECT * FROM t1 LEFT JOIN t2 ON t1.id=t2.id LEFT JOIN t3 ON t1.id = t3.id';
return st_cursor;
END REPORT_01;
CREATE OR REPLACE FUNCTION MASTER_REPORT (repId PLS_INTEGER)
RETURN resTable PIPELINED
IS
res resType := resType(NULL,NULL,NULL);
BEGIN
FOR rec in
( SELECT * FROM report WHERE REP_ID = repId )
LOOP
IF rec.basisreport_key = 'basisreport.einsaetzeimunternehmen' THEN
-- report_01 returns an open sys_refcursor
FOR rec2 IN report_01(rec.ben_id)
LOOP
-- PROBLEM HERE: "Invalid reference to variable 'REC2'"
res.c1 := rec2.personalnummer;
res.c2 := rec2.name;
res.c3 := rec2.type;
PIPE ROW(
END LOOP;
END IF;
END LOOP;
END MASTER_REPORT;
So my question is: How am i supposed to acces the contents of the returned ref cursor?
Thanks.
Ulrich PetriHello
Aha! Sorry, I forgot that for it to work you have to select the columns "as" the object type like so:
SQL> set serveroutput on
SQL> CREATE OR REPLACE TYPE resType AS OBJECT (
2 c1 VARCHAR2(80),
3 c2 VARCHAR2(80),
4 c3 VARCHAR2(80)
5 )
6 /
Type created.
SQL> DECLARE
2
3 my_cursor sys_refcursor;
4
5 res resType;
6
7 BEGIN
8
9 OPEN my_cursor FOR 'SELECT ''C1'',''C2'',''C3'' FROM DUAL';
10
11 FETCH my_cursor INTO res;
12
13 END;
14 /
DECLARE
ERROR at line 1:
ORA-00932: inconsistent datatypes: expected UDT got CHAR
ORA-06512: at line 11
SQL> DECLARE
2
3 my_cursor sys_refcursor;
4
5 res resType;
6
7 BEGIN
8
9 OPEN my_cursor FOR 'SELECT resType(''C1'',''C2'',''C3'') FROM DUAL';
10
11 FETCH my_cursor INTO res;
12
13 DBMS_OUTPUT.put_line(res.c1);
14 DBMS_OUTPUT.put_line(res.c2);
15 DBMS_OUTPUT.put_line(res.c3);
16
17 END;
18 /
C1
C2
C3
PL/SQL procedure successfully completed.HTH
David -
Returning a sys_refcursor for XML data in a function
As I typically write my queries in packages, and return sys_refcursor's to return data into a .NET DataSet via the OracleDataAdapter, I would like to know if it is possible to return the data using the OracleCommand.ExecuteXmlReader method to return XML results. None of the examples I have found delve into this area.
Versions:
ODP.NET : 10.2.X
.NET : 2.0
Firstly here is the function being called.
<code>
CREATE OR REPLACE FUNCTION XML_TEST_FUNC RETURN sys_refcursor
AS
l_serviceTable XML_SERVICE_TABLE_TYPE := XML_SERVICE_TABLE_TYPE();
l_badgeTable XML_BADGE_TABLE_TYPE := XML_BADGE_TABLE_TYPE();
l_cursor sys_refcursor;
BEGIN
FOR badgeRow IN (SELECT * FROM BADGE)
LOOP
FOR serviceRow IN (SELECT * FROM SERVICE WHERE BADGEID = badgeRow.BADGEID)
LOOP
l_serviceTable.extend;
l_serviceTable(l_serviceTable.last) := XML_SERVICE_ROW_TYPE(serviceRow.SERVICEID, serviceRow.SERVICENAME);
END LOOP;
l_badgeTable.extend;
l_badgeTable(l_badgeTable.last) := XML_BADGE_ROW_TYPE(badgeRow.BADGEID, badgeRow.BADGENAME, l_serviceTable);
END LOOP;
OPEN l_cursor FOR
SELECT * FROM TABLE(l_badgeTable);
RETURN l_cursor;
END;
</code>
XML_BADGE_ROW_TYPE and XML_SERVICE_ROW_TYPE are object types and XML_BADGE_TABLE_TYPE and XML_SERVICE_TABLE_TYPE are table objects.
I have done this as I want to return nested data of the Services that relate to a Badge.
Here is the C# code I am using to try and return the function results.
<code>
_command = new OracleCommand("XML_TEST_FUNC", _connection);
_command.CommandType = System.Data.CommandType.StoredProcedure;
_command.BindByName = true;
command.Parameters.Add(new OracleParameter("RETURNVALUE", OracleDbType.RefCursor));
_command.Parameters["RETURN_VALUE"].Direction = System.Data.ParameterDirection.ReturnValue;
_command.XmlCommandType = OracleXmlCommandType.Query;
_command.XmlQueryProperties.RootTag = "RESULT_SET";
_command.XmlQueryProperties.RowTag = "BADGE";
_command.XmlQueryProperties.MaxRows = -1;
_reader = _command.ExecuteXmlReader();
_document = new XmlDocument();
_document.PreserveWhitespace = true;
_document.Load(_reader);
</code>
All i get is the following error:
<error>
Oracle.DataAccess.Client.OracleException ORA-01036: illegal variable name/number
at Oracle.DataAccess.Client.OracleCommand.XmlHandleException(OracleException e)
at Oracle.DataAccess.Client.OracleCommand.ExecuteXmlQuery(Boolean wantResult)
at Oracle.DataAccess.Client.OracleCommand.ExecuteXmlReader()
at OracleXmlTestApp.Program.Main(String[] args) in D:\Projects\OracleXmlTestApp\OracleXmlTestApp\Program.cs:line 35
</error>
Any suggestion would be greatly appreciated.That does work, but I you want to aim for tidy XML it provides more than you would want. eg:
<ROWSET>
<ROW>
<XML_TEST_FUNC>
<XML_TEST_FUNC_ROW>
</XML_TEST_FUNC_ROW>
</XML_TEST_FUNC>
<XML_TEST_FUNC>
<XML_TEST_FUNC_ROW>
</XML_TEST_FUNC_ROW>
</XML_TEST_FUNC>
</ROW>
</ROWSET>In-between the <XML_TEST_FUNC_ROW> you do end up with the data you want, but the extra tags do not look crash hot.
I did attempt the use of the DBMS_XMLGEN package and was more successful where the output was more to my liking. eg:
<MyBadges>
<Badge>
<BadgeID>500000001</BadgeID>
<BadgeName>My Badge</BadgeName>
<Services>
<XML_SERVICE_ROW_TYPE>
<ServiceID>600000005</ServiceID>
<ServiceName>My Service</ServiceName>
</XML_SERVICE_ROW_TYPE>
</Services>
</Badge>
</MyBadges>The function called is as follows:
CREATE OR REPLACE FUNCTION XML_TEST_FUNC_2 RETURN XMLTYPE
AS
l_serviceTable XML_SERVICE_TABLE_TYPE := XML_SERVICE_TABLE_TYPE();
l_badgeTable XML_BADGE_TABLE_TYPE := XML_BADGE_TABLE_TYPE();
l_cursor sys_refcursor;
l_handle DBMS_XMLGEN.CTXHANDLE;
l_result XMLTYPE;
BEGIN
FOR badgeRow IN (SELECT * FROM BADGE)
LOOP
l_serviceTable := XML_SERVICE_TABLE_TYPE();
FOR serviceRow IN (SELECT * FROM SERVICE WHERE BADGEID = badgeRow.BADGEID)
LOOP
l_serviceTable.extend;
l_serviceTable(l_serviceTable.last) := XML_SERVICE_ROW_TYPE(serviceRow.SERVICEID, serviceRow.SERVICENAME);
END LOOP;
l_badgeTable.extend;
l_badgeTable(l_badgeTable.last) := XML_BADGE_ROW_TYPE(badgeRow.BADGEID, badgeRow.BADGENAME, l_serviceTable);
END LOOP;
OPEN l_cursor FOR
SELECT * FROM TABLE(l_badgeTable);
-- Get a handle to the XML document
l_handle := DBMS_XMLGEN.NEWCONTEXT(l_cursor);
-- Replace the default ROWSET tag with my own
DBMS_XMLGEN.SETROWSETTAG(l_handle, 'MyBadges');
-- Remove the default ROW level tag with my own
-- If I passed in text instead of NULL I would just change the element name
-- I can leave it off altogther and get the default, canonical format
DBMS_XMLGEN.SETROWTAG(l_handle, 'Badge');
-- Display null tags for empty columns
DBMS_XMLGEN.SETNULLHANDLING(l_handle, dbms_xmlgen.EMPTY_TAG);
-- Create an XML document out of the ref cursor
l_result := DBMS_XMLGEN.GETXMLTYPE(l_handle);
RETURN l_result;
END;with the C# code as such:
_command = new OracleCommand("XML_TEST_FUNC_2", _connection);
_command.CommandType = CommandType.StoredProcedure;
_command.Parameters.Add(new OracleParameter("RETURN_VALUE", OracleDbType.XmlType, ParameterDirection.ReturnValue));
_command.ExecuteNonQuery();
OracleXmlType _result = (OracleXmlType)_command.Parameters["RETURN_VALUE"].Value;
_result.GetXmlDocument().Save("C:\\output.xml");Maybe a bit more work, but better result.
Thanks for your help though, as it has provided other possiblities.
Maybe you are looking for
-
I can no longer connect to wi-fi on my iPad. The other computers in the house are connected, so it has to be the iPad. I tried resetting network settings, but it didn't help. What else can I do?
-
I somehow erased my video playing (and sound) ability on my iMac G5 running OS 10.5.8. When I tried downloading flash player from Adobe it said it was only for Intel based macs. Anyone know what precisely it is that I need to do to get video again?
-
No "New Video Recording" option
I just unlocked my Pro for Windows version. When I click on "File" there is no option for creating a new video, only a new audio. Does anyone know what this is about? The product is worthless to me if I cannot create video with it. Thanks ...
-
SAFARI crashing when trying to upload...PLEASE HELP.
greetings, I'm looking 4 help, and not sure if anyone else that uses safari is having same problem. Safari crashes and/or gives me an error when I try to upload files to the net. The two sites are really common (photbucket/dnbshare.com). Why is this
-
Reformat and install a new operating system
I need to completely reformat and erase all signs that a MacBook Pro was ever mine. Help?