Exception in implicit cursor
In the following block, I am unable to figure out how to catch
no_data_found in the SQL within the for loop.
no_data_found in the exception part doesn't catch it. Any ideas
would be much appreciated.
begin
for xx in(select ename from emp where hire_date > trunc(sysdate,'MM'))
loop
dbms_output.put_line('ename '||xx.ename);
end loop;
exception
when no_data_found then dbms_output.put_line('no record found');
end;
thanks.
arniko
The NO_DATA_FOUND exception is only raised when using an implicit cursor in PL/SQL. E.g.
select f.id into my_variable from foo f where f.day = trunc(sysdate);
..When opening a cursor, where you deal with the actual cursor handle (variable xx in your sample code), you use an explicit cursor reference. And in this case, the exception is not raised and you're expected to use the cursor variable called %NOTFOUND instead.
Similar Messages
-
Question on Synonyms and Implicit Cursor
Hi,
I've two doubts.
Question1:
Why Oracle is allowing me to create a synonym even base object does not exist in database.
For example in below example user ABC and object def doesnt exist in my database. Why I didnt get any error while creating a synonym.
Connected to Oracle Database 11g Express Edition Release 11.2.0.2.0
Connected as hr
SQL> CREATE SYNONYM test_syn FOR ABC.def;
Synonym created
SQL> Question2:
In PL/SQL after closing the cursor if we use any cursor attribute it will throw exception like invalid cursor. Why it is not happening in case of implicit cursor.
Or
Does Oracle close implicit cursor(SQL) ?
declare
begin
UPDATE emp
SET ename = 'SURI';
COMMIT;
dbms_output.put_line(SQL%rowcount);
end;Many thanks for all your help.
Cheers,
SuriSuri wrote:
Hi,
I've two doubts.
Question1:
Why Oracle is allowing me to create a synonym even base object does not exist in database.
For example in below example user ABC and object def doesnt exist in my database. Why I didnt get any error while creating a synonym.If you look in the all_dependencies view you will see that it's created as "NON-EXISTENT", so oracle knows it's non existent, it just doesn't treat it as an error.
As it says in the documentation:
http://docs.oracle.com/cd/E11882_01/server.112/e26088/statements_7001.htm#SQLRF01401
A dependency is created and if the target object is changed or dropped etc. the synonym becomes invalid... but that doesn't mean it cannot exist.
Question2:
In PL/SQL after closing the cursor if we use any cursor attribute it will throw exception like invalid cursor. Why it is not happening in case of implicit cursor.Would you care to demonstrate what you mean with some code. -
Avoid procedure or function calls between a SQL operation and an implicit cursor test
when i analyse this code with code expert
atpidgeon wrote:
when i analyse this code with code expert
UPDATE P_PM_CONTROL_COUNT
SET AVAIL_SEG = AVAIL_SEG -1,
ALLOCATION = ALLOCATION -1
WHERE PM_UNIT_TYPE_ID = vrectab(1)
AND USAGE_DATE = vrectab(2)
AND SEGMENT_CODE = vrectab(5)
AND ALLOCATION - UNITS_RESERVED > 0;
IF sql%rowcount = 0 then --Added block and exception to prevent invetory going negative when placing multi units in same unit type out of service.
vErrMsg := 'Could not process your out of service request because your selection for unit '|| vrectab(3) || ' at ' || pvPropertyId || ' for ' || vrectab(2) || ' would cause segment ' || vrectab(5) || ' to be over allocated.';
RAISE SegOverAllocated;
END IF;
i get "Avoid procedure or function calls between a SQL operation and an implicit cursor test.",as far has i know
iff you're doing a sql%rowcount after an update.. trying to see how many rows were updated... you dont want procedure or function calls between the update and the sql% line
correct me if im wrong and how would i fix it?or maybe i shouldnt
You correct it by NOT executing function calls as part of the UPDATE statement.
1. Issue the function calls BEFORE the update statement
2. save the function results into variables
3. use those variables in the UPDATE statement.
v_rectab1 := vrectab(1);
v_rectab2 := vrectab(21);
v_rectab5 := vrectab(5);
UPDATE P_PM_CONTROL_COUNT
SET AVAIL_SEG = AVAIL_SEG -1,
ALLOCATION = ALLOCATION -1
WHERE PM_UNIT_TYPE_ID = v_rectab1
AND USAGE_DATE = v_rectab2
AND SEGMENT_CODE = v_rectab5
AND ALLOCATION - UNITS_RESERVED > 0; -
Difference between implicit cursor and explicit cursor.
hi all,
i have used explicit cursor, i know the way of using implicit cursor, but i don't what the difference between both.
Is they both are different. if yes y? which cursor is most reliable to use.
please tell me..
Thanks..OK,
1- An IMPLICIT cursor is automatically declared by Oracle every time an SQL statement is executed The user will not be aware of this happening and will not be able to control or process
the information in an implicit cursor.
Example:
SET SERVEROUTPUT ON
BEGIN
UPDATE Customers
SET Cust_name = 'B'
WHERE Cust_name LIKE 'B%';
DBMS_OUTPUT.PUT_LINE(SQL%ROWCOUNT);
END;
2- An EXPLICIT cursor is defined by the program for any query that returns more than one row of data.
That means the programmer has declared the cursor within the PL/SQL code block. This declaration allows for the application to sequentially process each row of data as it is returned by the cursor.
Example :
DECLARE
CURSOR C_MyCursor IS
SELECT *
FROM bookings
WHERE Cust_no = 701;
see this post
http://comsci.liu.edu/~vasilaky/db2/cursors.htm :-) -
Hi,
Can anyone let me know how to close an implicit cursor opened for every individual sql statement? Please note that I am talking about the implicit cursor, not the explicit cursor. I am reaching the maximum open cursor limit and I don't want to increase the open_cursor parameter further as i have already set it a very big value (10000). Rather I would like to know how to close the implicit cursors opened by oracle itself.
Please help.
Thanks in advance.Thanks for your advice. In fact we have already
started re-constructing our coding using explicit
cursor. But the thing is even if the implicit cursors
are kept open till the session ending, it should be
closed when the maximum open_cursor limit is reached
by oracle itself.
The work arroud is well accepted, but I am very eager
to know whether somehow implicit cursor can be closed
or not.You have cursor leaks in your application. Are you closing the cursors? In JDBC (I know you said VB.Net but I don't know much about VB) you call the close method on the Statement objects. May be you are closing most of the cursors but a few are not being closed. In that case, the number of open cursors will slowly creep up to a high number. How often does this error come up? How long before you start seeing it?
Also, take a look at the v$open_cursor view (using your session SID) when you get the error and see if there are certain statements that are repeated a ton of times. This could help you find those statements that are not closed by the application.
Also note, there is a dbms_sql.close_cursor method. Check it out:
http://download-west.oracle.com/docs/cd/B10501_01/appdev.920/a96590/adg09dyn.htm#26799
-Raj -
Problem in using String in Implicit Cursor
Hi,
I am facing problem in using String in Implicit Cursor:
I have initialise
DECLARE
v_grant varchar2(4000);
begin
v_grant:='SELECT TABLE_NAME FROM DUMP_USER_TABLES WHERE TABLE_NAME LIKE ';
FOR obj IN (SELECT v_grant||'''BS%''' FROM dual) LOOP
V_REVOKE:='REVOKE ALL ON ' || 'obj.TABLE_NAME' || ' FROM ' || '''TEST''';
DBMS_OUTPUT.PUT_LINE('THE REVOKE STATEMENT IS'||V_REVOKE);
num := num + 1;
END LOOP;
END;
I am not getting the value from obj.TABLE_NAME its coming as 'obj.TABLE_NAME'
Kindly anyhelp will be needful for meBesides from what Sybrand already pointed out clearly:
Your example doesn't run at all:
MHO%xe> DECLARE
2 v_grant varchar2(4000);
3 begin
4 v_grant:='SELECT TABLE_NAME FROM DUMP_USER_TABLES WHERE TABLE_NAME LIKE ';
5 FOR obj IN (SELECT v_grant||'''BS%''' FROM dual) LOOP
6 V_REVOKE:='REVOKE ALL ON ' || 'obj.TABLE_NAME' || ' FROM ' || '''TEST''';
7 DBMS_OUTPUT.PUT_LINE('THE REVOKE STATEMENT IS'||V_REVOKE);
8 num := num + 1;
9 END LOOP;
10 END;
11 /
V_REVOKE:='REVOKE ALL ON ' || 'obj.TABLE_NAME' || ' FROM ' || '''TEST''';
FOUT in regel 6:
.ORA-06550: line 6, column 1:
PLS-00201: identifier 'V_REVOKE' must be declared
ORA-06550: line 6, column 1:
PL/SQL: Statement ignored
ORA-06550: line 7, column 49:
PLS-00201: identifier 'V_REVOKE' must be declared
ORA-06550: line 7, column 1:
PL/SQL: Statement ignored
ORA-06550: line 8, column 1:
PLS-00201: identifier 'NUM' must be declared
ORA-06550: line 8, column 1:
PL/SQL: Statement ignoredI guess you need to read up on quoting strings properly and probably also dynamic SQL.
But:
WHAT are you trying to do anyway?
I cannot parse your code at all...so what is your requirement in human language? -
Sql exception : maximum open cursors exceeded
I run applicatio to insert data into the table, and update data into the table, when it processes more than 800 record, it throws the sql exception :maximum open cursors exceeded.
Who knows the reason?
Thanks.I have a similar problem where in I close the Result set, Statement and close the connection in a finally block. Even though, the connection.close() executes sucessfully, with no exceptions being thrown, I still see the connection opened in ORacle. This builds up connections for our application and by the end of the day we are up with about 500 connections open and rising.
After closing the connection, I did check the value for connection.isClosed() and it still says false (like before the connection was closed). Since we are using a custom Connection manager to pool the connections, my interpretation is that even after the connection is closed, it doesn't get released. I have tried setting the connection to Null, used the finalize method to still check for connection != null and do one more close(), but still the connection is still open.
Am I mistaken in my thinking that even though the connection seems to be closed(), it doesn't get released until the GC runs and picks it for disposal? For every job, after the process is completed we have about 7 open connections and at times the number stays at 7 for some more jobs (Web application driven by servlets and some rmi in the background process). I thne see a surge in the connection after some more jobs are processed and so am not sure whether its the connection manager to blame. Could any one have any pointers on this issue.
Thanks for your response. -
How to fetch NO DATA FOUND exception in Ref Cursor.
In my procedure ref cursor is out parameter with returns dataset. in my proceudre
its like...
OPEN pPymtCur FOR
select.....
when I call this procedure from report to get dataset it causes NO DATA FOUND exception.
How to fetch this exception in my oracle procedure so I can get some other data.
Any Idea to do this?
Edited by: Meghna on 17-Jun-2009 22:28Mass25 wrote:
Correct me if I am wrong.
So if I do something as follows in my stored proc, I do not have to check for NO_DATA_FOUND?
OPEN my_CuRSR FOR
SELECT DISTINCT blah blah blahmy_cursr is what I am returning as OUT param in my SP.Correct. At the point you open the cursor, oracle has not attempted any 'fetch' against the data so it won't know if there is any data or no data. that only occurs when a fetch is attempted.
Take a read of this:
[PL/SQL 101 : Understanding Ref Cursors|http://forums.oracle.com/forums/thread.jspa?threadID=886365&tstart=0] -
Exception while Registering Cursor Output Param
Hi All,
I am Trying to call a SP through java class. The SP has one of its output as CURSOR object.
now during runtime when callableStatement.registerOutputParam () is called on that cursor object
an SQL Exception is thrown giving mesasge as Invalid Column Index.
Can Anyone please help me as to what may be the problem here.
I have checked a number of times and the parameter index of the Cursor Object is correct.
Thanks in advance.
Regards,
Sumbul.hi All,
Can anyone please elaborate on the previous thread.
I am still not able to execute the Procedure.
From where should I match the Output Parameter index of my java code.
Regards,
Sumbul.
Edited by: user10583473 on Jul 30, 2010 7:54 PM -
Type Mismatch using Implicit Cursor
The actual error I get is
PLS-00386: type mismatch found at 'EMP_REC' between FETCH cursor and INTO variables
I have copied the code in below (taken some logic out to make example easier). I think the problem is with the EMP_REC CHILDKNOWDES declaration - I dont think I need to add %ROWTYPE? Is the type mismatch a case of trying to parse an int into a string (which i have checked for), or a case of the object being stored with attributes in dif order (alphabetical?), or is something more sinister going on?
CREATE OR REPLACE TYPE &HKDB_Schema_Name..CHILDKNOWDES AS OBJECT
KnowdeID INT,
Description varchar2(512),
Connector CHAR(1),
WhyCount INT
CREATE OR REPLACE TYPE &HKDB_Schema_Name..TEMP_CHILDKNOWDES_TABLE AS TABLE OF &HKDB_Schema_Name..CHILDKNOWDES;
CREATE OR REPLACE PROCEDURE &HKDB_Schema_Name..QueryChildKnowdes
aKnowdeID int,
aCur out sys_refcursor
AS
l_ChildKnowdeTable TEMP_CHILDKNOWDES_TABLE := TEMP_CHILDKNOWDES_TABLE();
EMP_REC CHILDKNOWDES;
BEGIN
DECLARE CURSOR c1 is SELECT k.KnowdeID, k.Description, KnowdeAssociation.Connector
FROM Knowde k
INNER JOIN KnowdeAssociation ka on ka.KnowdeID = k.KnowdeID
BEGIN
OPEN c1;
FETCH c1 INTO EMP_REC; --error
WHILE c1%FOUND
LOOP
BEGIN
QueryWhyCount(EMP_REC.KnowdeID, aWhyCountResult);
l_ChildKnowdeTable.extend;
l_ChildKnowdeTable(l_ChildKnowdeTable.last) := CHILDKNOWDES
(EMP_REC.KnowdeID,
EMP_REC.Description,
EMP_REC.Connector,
aWhyCountResult);
FETCH c1 INTO EMP_REC; --error
END;
END LOOP;
END;
END QueryChildKnowdes;Thanks in advance,
TobyKnowde
Name Null? Type
KNOWDEID NOT NULL NUMBER(10)
VERBID NOT NULL NUMBER(10)
NOUNID NOT NULL NUMBER(10)
KGID NOT NULL NUMBER(10)
DATECREATED NOT NULL DATE
DESCRIPTION VARCHAR2(51
UDRID NUMBER(10)
UVRID NUMBER(10)
RESOURCEID NUMBER(10)
VERSIONID NUMBER(10)
CHECKEDOUT NUMBER(1)
CLIENTKNOWDEID NUMBER(10)
GENERICKNOWDEID NUMBER(10)
SOURCEKNOWDEID NUMBER(10)
UNEDITABLE NUMBER(1)
DATEUPDATED NOT NULL DATE
PREVIOUSKNOWDEID NUMBER(10)KnowdeAssociation
Name Null? Type
KNOWDEASSOCIATIONID NOT NULL NUMBER(10)
HOWID NOT NULL NUMBER(10)
WHYID NOT NULL NUMBER(10)
CONNECTOR CHAR(1)
HOWCHAINPOSITION NUMBER(10)
WHYCHAINPOSITION NUMBER(10) -
Is it good to use For implicit cursors to fetch only one row ?
I mean is it good to use something below.
function isThereAny (inCompany) return boolean is
begin
for x in ( select 'x' from company_relation
where company=inCompany
and nvl(europe_yn,'N')='Y' ) loop
return true;
end loop;
return false;
end isThereAny; ThanksThis construction seems to be approximately 10% faster than a regular select into on 9.2.0.7.0. But I think the code is less clear for maintenance than a regular select into. When I look at the code, my first thought is it is going to loop through some records, and on second thought it is not. I don't like that, but it is a matter of personal taste.
When you don't have problems with that or when you really need that 10% on the function, it is perfectly ok.
SQL> create function isThereAny_for (p_deptno in dept.deptno%type) return boolean
2 is
3 begin
4 for x in
5 ( select 'x'
6 from emp
7 where deptno = p_deptno
8 and nvl(comm,0) > 0
9 )
10 loop
11 return true;
12 end loop
13 ;
14 return false
15 ;
16 end isThereAny_for;
17 /
Functie is aangemaakt.
SQL> create function isThereAny_into (p_deptno in dept.deptno%type) return boolean
2 is
3 l_x varchar2(1);
4 begin
5 select 'x'
6 into l_x
7 from emp
8 where deptno = p_deptno
9 and nvl(comm,0) > 0
10 ;
11 return true;
12 exception
13 when no_data_found then
14 return false;
15 when too_many_rows then
16 return true;
17 end isThereAny_into;
18 /
Functie is aangemaakt.
SQL> begin
2 -- Warming up
3 for i in 1..4
4 loop
5 if isThereAny_for(i*10)
6 then
7 null;
8 end if;
9 end loop;
10 for i in 1..4
11 loop
12 if isThereAny_into(i*10)
13 then
14 null;
15 end if;
16 end loop;
17 -- Start test
18 runstats_pkg.rs_start;
19 for i in 1..10000
20 loop
21 if isThereAny_for((mod(i,4)+1)*10)
22 then
23 null;
24 end if;
25 end loop;
26 runstats_pkg.rs_middle;
27 for i in 1..10000
28 loop
29 if isThereAny_into((mod(i,4)+1)*10)
30 then
31 null;
32 end if;
33 end loop;
34 runstats_pkg.rs_stop(100);
35 end;
36 /
Run1 draaide in 200 hsecs
Run2 draaide in 216 hsecs
Run1 draaide in 92,59% van de tijd
Naam Run1 Run2 Verschil
LATCH.simulator hash latch 154 439 285
LATCH.redo allocation 2,530 2,817 287
LATCH.row cache enqueue latch 140 494 354
LATCH.sequence cache 3,614 4,006 392
LATCH.row cache objects 384 791 407
LATCH.library cache pin 34,415 36,019 1,604
LATCH.shared pool 17,207 18,929 1,722
LATCH.library cache 35,591 37,587 1,996
STAT.table scan rows gotten 110,000 112,500 2,500
STAT.db block gets 12 5,015 5,003
STAT.session logical reads 30,017 35,023 5,006
STAT.recursive calls 12,501 20,001 7,500
LATCH.cache buffers chains 113,839 134,592 20,753
Run1 latches totaal versus run2 -- verschil en percentage
Run1 Run2 Verschil Pct
208,826 236,934 28,108 88.14%
PL/SQL-procedure is geslaagd.Regards,
Rob. -
Hello,
since migrating our system from Oracle Client 9.0.X to 9.2.0.1 (Windows XP), i am encountering troubles when calling a stored procedure from a Cobol-Program:
after a while i run into a 'Maximum open cursors exceeded'-message (ORA-01000)
The stored procedure returns a cursor (ref_cursor)
When Executing the stored procedure, there are actually 2 cursors involved, in fact the stored PL/SQL procedure implicitely opens a child-cursor when doing a select within the PL/SQL.
After fetching the result and closing the cursor in my cobol-program, it correctly closes the cursor associated with the stored-procedure, but it does not close the cursor that was implicitely opened by oracle.
After a while i am running into a Maximum open cursors message, because those cursors have not properly been closed.
Here's a simple PL/SQL package that illustrates the problem:
create or replace package scott.SCOTTS_PACKAGE is
type ref_cursor IS REF CURSOR;
function GET_EMP(EMP_IN CHAR) return ref_cursor;
end SCOTTS_PACKAGE;
create or replace package body scott.SCOTTS_PACKAGE is
-- Function and procedure implementations
function GET_EMP(EMP_IN CHAR) return ref_cursor is
MyCurs ref_cursor;
begin
OPEN MyCurs FOR
SELECT EMPNO ,
ENAME ,
JOB
FROM SCOTT.EMP
WHERE ENAME = EMP_IN;
return(MyCurs);
end;
end SCOTTS_PACKAGE;
Here are some exerpts from my cobol program:
(The program iterates 100x through the section that executes the PL/SQL. After each iteration an additional open cursor remains in the database)
003800 EXEC SQL BEGIN DECLARE SECTION END-EXEC.
003900*
004000 01 SQL-USERNAME PIC X(16) VARYING.
004100 01 SQL-PASSWD PIC X(16) VARYING.
004200 01 SQL-DBNAME PIC X(64) VARYING.
004300 01 ORACLE.
004700 02 ORA-CUR-EMP SQL-CURSOR.
01 EMPREC.
02 EMPREC-EMPNO PIC X(4).
02 EMPREC-ENAME PIC X(10).
02 EMPREC-JOB PIC X(9).
005400 EXEC SQL END DECLARE SECTION END-EXEC.
018400 PROCEDURE DIVISION.
CONTINUE.
018700 EXEC SQL
018800 WHENEVER SQLERROR DO PERFORM SQL-ERROR
018900 END-EXEC.
019000*
CONTINUE.
019100 EXEC SQL
019200 WHENEVER NOT FOUND DO PERFORM SQL-NOT-FOUND
019300 END-EXEC.
022400 EXEC SQL
022500 ALLOCATE :ORA-CUR-EMP
022600 END-EXEC
PERFORM VARYING I FROM 1 BY 1 UNTIL I > 100
ACCEPT DUMMY FROM TER
IF DUMMY = "E"
MOVE 100 TO I
END-IF
PERFORM GET-EMP
ADD 1 TO I
END-PERFORM
119300 GET-EMP SECTION.
119400************************
119500 GAM0.
MOVE SPACES TO EMPREC-EMPNO EMPREC-JOB
MOVE "SMITH" TO EMPREC-ENAME
120200 EXEC SQL AT SSSI EXECUTE
120300 BEGIN
120400 :ORA-CUR-EMP:=
120500 SCOTT.SCOTTS_PACKAGE.GET_EMP(:EMPREC-ENAME );
120900
END;
121000 END-EXEC
121200 IF DB-ERR-CODE NOT = HIGH-VALUE
121300 DISPLAY "CCSIFSO:GET-AUTRE-MATR:APPEL PERS... OK"
121400 EXEC SQL
121500 FETCH :ORA-CUR-EMP
121600 INTO
121700 :EMPREC-EMPNO,
121800 :EMPREC-ENAME,
121900 :EMPREC-JOB
122400 END-EXEC
122500 END-IF
122600*
122700 IF DB-ERR-CODE NOT = HIGH-VALUE
122800 DISPLAY "CCSIFSO:GET-AUTRE-MATR:APPEL FETCH.. OK"
123000 ELSE
123100 MOVE LOW-VALUE TO DB-ERR-CODE
123200 END-IF
123300 EXEC SQL
123400 CLOSE :ORA-CUR-EMP
123500 END-EXEC
123600 GA-EX.
123700 EXIT.
124000 SQL-NOT-FOUND SECTION.
124100*----------------------
124200 NF0.
124300 DISPLAY "CCSIFSO:SQL-NOT-FOUND SECTION."
124400 MOVE HIGH-VALUE TO DB-ERR-CODE.
124500 NF-EX.
124600 EXIT.
124700*
124800 SQL-ERROR SECTION.
124900*-----------------
125000 ER0.
125200 EXEC SQL
125300 WHENEVER SQLERROR CONTINUE
125400 END-EXEC
125700 MOVE HIGH-VALUE TO DB-ERR-CODE
125800*
126100 DISPLAY "ORACLE ERROR DETECTED: " SQLCODE UPON TER
126200 DISPLAY SQLERRMC UPON TER
126300*
126400 EXEC SQL AT SSSI
126500 ROLLBACK WORK
126600 RELEASE
126700 END-EXEC
126800 DISPLAY "----------------------------" UPON TER
126900 DISPLAY " ! ROLLBACK ET DISCONNECT ! " UPON TER
127000 DISPLAY "----------------------------" UPON TER
127200 CALL "PPTERMJ".
127400 ER-EX.
127500 EXIT.
Finally here's an exerpt from V$OPEN_CURSOR, after a few iterations:
1 begin :b1 := SCOTT . SCOTTS_PACKAGE . GET_EMP (:b2 ) ; END ;
2 SELECT EMPNO , ENAME , JOB FROM EMP WHERE ENAME = :B1
3 SELECT EMPNO , ENAME , JOB FROM EMP WHERE ENAME = :B1
4 SELECT EMPNO , ENAME , JOB FROM EMP WHERE ENAME = :B1
5 SELECT EMPNO , ENAME , JOB FROM EMP WHERE ENAME = :B1
6 SELECT EMPNO , ENAME , JOB FROM EMP WHERE ENAME = :B1
7 SELECT EMPNO , ENAME , JOB FROM EMP WHERE ENAME = :B1
8 SELECT EMPNO , ENAME , JOB FROM EMP WHERE ENAME = :B1
9 SELECT EMPNO , ENAME , JOB FROM EMP WHERE ENAME = :B1
10 SELECT EMPNO , ENAME , JOB FROM EMP WHERE ENAME = :B1
11 SELECT EMPNO , ENAME , JOB FROM EMP WHERE ENAME = :B1
As you see, there is only 1 cursor starting with 'begin ... '
but there are 10 implicit cursors 'SELECT EMPNO, ... ' that have not been properly closed, nor reused by ORACLE.
In our old configuration (ORACLE CLient 9.0.X), you would only see:
1 begin :b1 := SCOTT . SCOTTS_PACKAGE . GET_EMP (:b2 ) ; END ;
2 SELECT EMPNO , ENAME , JOB FROM EMP WHERE ENAME = :B1
meaning all the other cursors have properly been closed.
As a conclusion: the program correctly closes the implicit cursors when using a 9.0 Client, wheras the implicit cursors remain open on Client 9.2.0.1 (Windows XP)
The underlying database can be either 8.i or 9, the problem remains the same.
Finally here's a small Delphi code, using ODAC-components, that somewhat illustrates the same problem:
procedure TForm1.ExecProcClick(Sender: TObject);
var I: INTEGER ;
begin
FOR I := 1 TO 5 DO
BEGIN
SP1.StoredProcName:='SCOTT.SCOTTS_PACKAGE.GET_EMP';
SP1.Prepare;
SP1.ParamByName('EMP_IN').AsString := 'SMITH';
SP1.ExecProc;
SP1.Next;
SP1.Close;
SP1.UnPrepare;
END;
end;
After each call to 'PREPARE', an additional implicit cursor remains open on the database. (using Oracle Client 9.2.0.1)
On our old system (Oracle Client 9.0 or 8.X), the same program would not generate accumulating open cursors on the database
Any suggestions would be welcome,
ClaudeCobol.. been many years since I last even saw some Cobol source code. Invokes all kinds of memories. :-)
Since you found the patch, the advice is superfluous, but works. Close the cursor at the PL/SQL side, e.g.
create or replace procedure CloseRefCursor( cRefCursor TYPELIB.TRefCursor ) is
begin
close cRefCursor;
exception when OTHERS then
-- if the cursor is already gone, not a problem
NULL;
end;In Delphi for example, one can subclass the class used for ref cursor calls and add a call to the above PL/SQL proc in the destructor. Or add create a standard Cobol close ref cursor section that does similar. -
Handling no_Data_found and handling the cursor context not found exceptions
hi all,
when the value is not there in table, we will get the no_data_found exception.
im sending the sample procedure.
check that one.
create or replace procedure registration.P_GetPatientDetails(in_UHID in Patient.Uhid%Type,
ocursor_Component1 OUT SYS_REFCURSOR,
---ocursor_Component2 OUT SYS_REFCURSOR,
ocursor_Component3 OUT SYS_REFCURSOR,
ocursor_Component4 OUT SYS_REFCURSOR
AS
in_RegistrationID varchar2(50);
ln_genderLovID NUMBER(10);
ln_rhfactorLovID NUMBER(10);
BEGIN
SELECT RegistrationId
into in_RegistrationID
from Patient
where (Upper(UHID) = Upper(in_UHID)) ;
/* COMMIT;*/
/*dbms_output.put_line(in_RegistrationID);*/
OPEN ocursor_Component1 FOR
SELECT RegistrationID,PreRegistrationNo,EmergencyNo,UHID
FROM patient p LEFT OUTER JOIN EHIS.Titlemaster TM ON p.title = tm.titlecode LEFT OUTER JOIN EHIS.SuffixMaster SM on p.sufix = SM.SUFFIXCODE LEFT OUTER JOIN EHIS.Maritalstatusmaster MSM ON MSM.MARITALSTATUSID = p.maritalstatus LEFT OUTER JOIN EHIS.Bloodgroupmaster BGM ON BGM.BLOODGROUPID = p.bloodgroup LEFT OUTER JOIN EHIS.LovDetail LD ON(LD.LOVDETAILID = p.gender AND LD.LOVID = ln_genderLovID) LEFT OUTER JOIN EHIS.LovDetail rf ON(rf.LOVDETAILID = p.rhfactor AND rf.LOVID = ln_rhfactorLovID)
WHERE RegistrationID = in_RegistrationID AND p.Status = 1 ;
OPEN ocursor_Component3 FOR
SELECT RegistrationID,ResidenceNumber,MobileNumber,PrimaryEmail
FROM AddressMaster
WHERE UPPER(RegistrationID) = UPPER(in_RegistrationID) AND Status = 1 AND
AddressTypeID =
(SELECT AddressTypeID
FROM AddressTypeMaster
WHERE AddressTypeName = 'PermanentAddress');
/* COMMIT;*/
OPEN ocursor_Component4 FOR
SELECT ResidenceNumber, MobileNumber,EmergencyNumber,PrimaryEmail
FROM AddressMaster am LEFT OUTER JOIN EHIS.Countrymaster CM ON CM.COUNTRYID = am.country LEFT OUTER JOIN EHIS.Statemaster SM ON SM.STATEID = am.state LEFT OUTER JOIN EHIS.Districtmaster DM ON DM.DISTRICTID = am.district LEFT OUTER JOIN EHIS.Citymaster CM1 ON CM1.CITYID = am.city
WHERE UPPER(RegistrationID) = UPPER(in_RegistrationID) AND Status = 1 AND
AddressTypeID =
(SELECT AddressTypeID
FROM AddressTypeMaster
WHERE AddressTypeName = 'CurrentAddress');
/* COMMIT;*/
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(TO_CHAR(SQLCODE) || SQLERRM);
END;
if the data is not there for teh given uhid,
we are displaying the err msg in exception block
but from .net environment ,
they will define the cursors as out params.
if they wont get the data,
in .net environment, the exception is raised.
how to handle these situations.Implicit cursors are prone to both the NO_DATA_FOUND and TOO_MANY_ROWS errors. They MUST return precisely one row or you get to do extra coding in the form of exception handlers. Using explicit cursors (declared in the DECLARE SECTION) will avoid both errors, though they have their own considerations. When an explict cursor doesn't find something it doens't put NULL into the destination variable(s); it leaves them alone so its a good idea to null out variables and records before fetching into them.
-
Hi,
I have a small code with implicit cursor to fetch rows from table unreadable_cards and then for each value fetched I lookup another table card_acnt for some values and update data in unreadable cards table. The code is as below
declare
v1 number;
begin
for v1 in (select engravedid from unreadable_cards where case_resolved=1)
loop
update unreadable_cards set serial_number = (select serial_number from card_account
where ticketid = v1.engravedid)
where engravedid = v1.engravedid;
update unreadable_cards set case_resolved=2
where case_resolved=1
and serial_number is not null;
end loop;
exception
when no_data_found then
update unreadable_cards set case_resolved=22
where ticketid = v1.engravedid;
when too_many_rows then
update unreadable_cards set case_resolved=23
where ticketid = v1.engravedid;
when others then
update unreadable_cards set case_resolved=24
where ticketid = v1.engravedid;
end;
Here I have problem writing values to the table as this error pops up for every reference to V1 in exception
PLS-00487: Invalid reference to variable 'V1'
I need to be able to raise all three exceptions within the loop so that v1 can be referenced and loop does not exit on encountering the exception and completes for every row fetched by cursor, so that I can track the status of each record on the basis of case_resolved value.
Any help would be highly appreciated
Thanks
SaurabhLet me get that out of me.. I don't like your code
First thing you need to know is, you are not going to hit NO_DATA_FOUND exception in a UPDATE statement. If a update did not modify any row it will not raise NO_DATA_FOUND exception. Check this out
SQL> begin
2 update emp set sal = sal+ 10 where 1=2;
3 end;
4 /
PL/SQL procedure successfully completed.
No exception there. So that is one thing you need to look at.
Second thing I don't like the way you have used WHEN OTHERS exception. What are the exception you are looking at? You should not be having a when others without RAISE. It a bug in the code. You need to fix that.
Assuming your logic behind assigning CASE_RESOLVED is like this.
CASE_RESOLVED = 2 means you have found an exact match for your UNREADABLE_CARDS.ENGRAVEDID in CARD_ACCOUNT.TICKETID
CASE_RESOLVED = 22 means you don't have a match for your UNREADABLE_CARDS.ENGRAVEDID in CARD_ACCOUNT.TICKETID
CASE_RESOLVED = 23 means you have multiple match for your UNREADABLE_CARDS.ENGRAVEDID in CARD_ACCOUNT.TICKETID
CASE_RESOLVED = 24 This does not make any sense. You need to drop this part.
You can do this, You don't need all that PL/SQL. Just a simple SQL like this will do.
merge into unreadable_cards x
using (
select a.engravedid
, max(b.serial_number) serial_number
, case when count(b.serial_number) = 1 then 2
when count(b.serial_number) = 0 then 22
when count(b.serial_number) > 1 then 23
end case_resolved
from unreadable_cards a
left
join card_account b
on a.engravedid = b.eticketid
where a.case_resolved = 1
group
by a.engravedid
) y
on (
x.engravedid = y.engravedid
when matched then
update set x.serial_number = nvl(y.serial_number, x.serial_number)
, x.case_resolved = y.case_resolved;
Above is a untested code. But should work. If any minor error fix it and you should be good to go. -
What is implicit and explicit cursor ?
I need to know what is implicit cursor and what is Explict one with a sample source.
Also what is the difference between these two?
Thank youCheck this:
http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14261/sqloperations.htm#sthref1274
Maybe you are looking for
-
What is wrong with my Macbook Pro? (distorted screen, beeping, slow)
I have a late 2012 Macbook Pro (13-inch) that I got from Best Buy. It worked perfectly fine for a year, but then went crazy. First, it started shutting down here and there, and icons bounced a lot in the dock. Then, one day, I googled something and i
-
During the start up of my imac, logon failed
during the start up of my imac, logon failed and the user doesn't exit anymore . i have performed a password recovery and i'm using the mac root user. is it possible to recover my user and my profile ? and how ? this problem exist from the moment in
-
Sk17i Video streaming on WiFi problems.
andriod 2.3.4 build 4.0.2.A.0.58Flash version... Lastest.Apps with push notifcations... All disabled... well, i stopped auto snyc.Internet speed: 20mb/s Unlimited (Sky)Wifi speed: 14mb/s (using speedtest.net's app)Other devices using wifi? none.Dista
-
Missing Camera Raw in PSE11?
I purchased PSE 11 and do not have the plug-in Camera Raw. I have tried the solutions suggested in the main Adobe help page without success. A friend bought a copy at the same time and she has the plug-in. Any suggestions why I do not have it? I have
-
I finished a project and I'm content with it, but I want to try a couple of different transitions without messing the entire thing up. Basically, I want to experiment with it. Is there any way to save a project as a copy and then work on the copy?