Skip to Main Content
  • Questions
  • Does PL/SQL Implicitly close cursors?

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, Giridhar.

Asked: July 19, 2005 - 10:50 pm UTC

Last updated: July 20, 2005 - 12:38 pm UTC

Version: 9.2.0

Viewed 1000+ times

You Asked

Hi tom,
Good Morning.
While reading PL/SQL book, there is a reference to the link below which discusses about how PL/SQL deals with open cursors.


</code> http://www.gennick.com/open_cursors.html <code>

At the end of the article, it is mentioned as follows:
--------------------------------------------------------------
Do you wonder why the cursor math doesn't work out? I do to. I'm sure one cursor is necessary to execute my anonymous block. But one cursor to execute the anonymous block + 48 cursors opened in the inner block + 1 cursor opened in the outer block = 50 cursors. I should have been able to open 50 cursors, so what put me over the limit? Is another cursor opened to execute the inner block? If you know the answer, please let me know. Regardless, it's clear that PL/SQL is NOT implicitly closing cursors at the end of a block.
--------------------------------------------------------------

can you please explain why we are not able to open 50 cursors here?

Thanks tom.

Regards,
Giridhar

and Tom said...

he was runnnig in sqlplus, sqlplus has stuff open as well (dbms_output for example, it might have a dbms_output.get_lines call parsed)


I didn't have such a cursor

ops$tkyte@ORA10GR1> show parameter open_cursors

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
open_cursors integer 50
ops$tkyte@ORA10GR1> @test

PL/SQL procedure successfully completed.

ops$tkyte@ORA10GR1> l 100 *
100 OPEN test47;
101 OPEN test48;
102 END;
103
104 --This last OPEN will cause an error
105 --from too many cursors.
106 OPEN last99;
107* END;
ops$tkyte@ORA10GR1>


in my session so it works. SQLPlus, when used as the test tool, must be looked at too.


adding another cursor:

ops$tkyte@ORA10GR1> @test
DECLARE
*
ERROR at line 1:
ORA-01000: maximum open cursors exceeded
ORA-06512: at line 3
ORA-06512: at line 108


ops$tkyte@ORA10GR1> l 100 109
100 OPEN test46;
101 OPEN test47;
102 OPEN test48;
103 END;
104
105 --This last OPEN will cause an error
106 --from too many cursors.
107 OPEN last99;
108 OPEN last100;
109* END;
ops$tkyte@ORA10GR1>

so that showed that plus just had something else open in his release.


but, just to add a twist :)


ops$tkyte@ORA10GR1> show parameter open_cursor

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
open_cursors integer 50

ops$tkyte@ORA10GR1> DECLARE
2 procedure p
3 is
4 cursor c is select * from dual;
5 begin
6 open c;
7 end;
8 BEGIN
9 for I in 1 .. 100
10 loop
11 p;
12 end loop;
13 END;
14 /

PL/SQL procedure successfully completed.




Rating

  (4 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

A reader, July 20, 2005 - 8:17 am UTC

OK, if someone innocent is supposed to ask a question, I will represent:

1)What's happening to the cursors, Guess: they are being Cached out by some internal LRU?


Tom Kyte
July 20, 2005 - 8:42 am UTC

no, it was to compare the nested begin/end block of Jonathan Gennick with calling the embedded function and observing that the scoping rules are different.


when we call the function 100 times, the cursor is closed each and every time.

if you have that big embedded block that defines a "sub scope" in the greater scope -- then they are not closed until that block exits

but Jonathan's conclusion is 100% dead on: if you open a cursor, close it - it is a bug in your code if you do not. Do not rely on this behavior, write the code right.

Ravi, July 20, 2005 - 9:04 am UTC

Any relation to PL/SQL's implicit 'Keep Cursor Open' phenomenon as described in
</code> http://metalink.oracle.com/metalink/plsql/ml2_documents.showDocument?p_database_id=NOT&p_id=166336.1 <code>

I do not have access to V$OPEN_CURSOR, but if I had opened a slightly different cursor in the procedure like

DECLARE
counts number(10):=0;
procedure p
is
cursor c is select sysdate+counts from dual;
d date;
begin
open c;
fetch c into d;
counts := counts+1;
end;
BEGIN
for I in 1 .. 1000
loop
p;
end loop;
END;
/

Would PL/SQL keep a 1000 cursors open now, but don't tell us, all in good intents, ofcourse?

Tom Kyte
July 20, 2005 - 12:38 pm UTC

the plsql cursor cache handles the cursors that are logically closed by plsql, but not physically closed.

Oracle 9i and 10G

Giridhar, July 20, 2005 - 9:56 am UTC

Hi Tom,
Thanks for your reply. I have one doubt.
Jonathan Gennick's article was on oracle 9i and your example is on oracle 10G. May i know whether you are able to reproduce this even in oracle 9i. As i dont have access to oracle 10G database, i am not able to test in 10G.

Regards,
Giridhar

A reader, July 20, 2005 - 11:12 am UTC

It works the same way in both 9i and 10g

More to Explore

PL/SQL demos

Check out more PL/SQL tutorials on our LiveSQL tool.

PL/SQL docs

PL/SQL reference manual from the Oracle documentation library