In this Document
Purpose |
Scope |
Details |
References |
This article contains information on how different cursors are managed and monitored in PL/SQL.
It addresses issues with the open_cursors parameter, as well as the V$OPEN_CURSOR view in the context of implicit, declared, and dynamic cursors.
This section covers the monitoring and managing of the open cursors.
The number of open cursors can limit operation in PL/SQL procedures and SQL*Plus sessions. While the parameter open_cursors sets the limit, programming issues can cause the following error:
ORA-1000 maximum open cursors exceeded
Three important values are the following:
These values are similar, but differ in their accounting of Dynamic Cursors.
Note: Dynamic cursors are those opened using DBMS_SQL.OPEN_CURSOR().
The means to compute those values are as follows:
View v$open_cursor
The following SQL calculates the:
implicit cursors used + distinct explicit cursors opened + dynamic cursors PARSED and NOT CLOSED.
It also:
- Accumulates dynamic cursors PARSED and NOT CLOSED over a session
- Available to system/manager
- Includes the text of open cursors - helpful for debugging
- Since this view does not track unparsed (but opened) dynamic cursors,
the count(*) may not show all cursors that count against open_cursors.
SQL> select count(*) from v$open_cursor;
COUNT(*)
----------
139
View v$sysstat
The following SQL calculates the:
implicit cursors used + distinct explicit cursors opened + dynamic cursors OPENED.
It also:
- Accumulates dynamic cursors OPENED and NOT CLOSED over a session
- Available to system/manager
- Since this view does track unparsed (but opened) dynamic cursors, the statistic#3 shows all cursors that count against open_cursors.
SQL> select value from v$sysstat where statistic# = 3;
VALUE
----------
37
OR
You can join with v$statname as Statistics numbers are not guaranteed to remain constant from one release to another.
SQL>select value from v$sysstat sy , gv$statname st
where sy.statistic# = st.statistic#
and st.name = 'opened cursors current';
VALUE
----------
37
init.ora parameter open_cursors
This parameter equal:
implicit cursors used + distinct explicit cursors opened + dynamic cursors OPENED.
It also:
- Accumulates dynamic cursors OPENED and NOT CLOSED over a session
SQL> show parameters open_cursor
NAME TYPE VALUE
------------------ ----------- ---------
open_cursors integer 300
ORA-1000
The following are several items to check when encountering ORA-1000 in PL/SQL:
1. Be sure that all dbms_sql cursors opened at DECLARE time are closed. Every unclosed OPEN counts against open_cursors. The number of open cursors can be determined as follows in SQL*Plus:
SQL> select value from v$sysstat where statistic# = 3;
OR
SQL>select value from v$sysstat sy , gv$statname st
where sy.statistic# = st.statistic#
and st.name = 'opened cursors current';
2. Be aware that v$open_cursor only tracks the CUMULATIVE number of implicit + distinct explicit cursors in the procedure PLUS unclosed dynamic cursors that have been PARSED in the session.
Note: It does not include any dynamic cursors that were opened but not parsed.
The text of the parsed, open cursors can be determined as follows in SQL*Plus:
SQL> select sql_text from v$open_cursor;
3. Dynamic cursors persist from run-to-run in a session, but are not closeable after a procedure has completed. This can accumulate and error-out with open_cursors after a number of runs. They will not
appear in v$open_cursors after a session.
The following are two code snippets that can help diagnose ORA-1000. Text lines are shown for each cursor.
-- snippet 1
set serveroutput on
declare
cursor opencur is select * from v$open_cursor;
ccount number;
begin
select count(*) into ccount from v$open_cursor;
dbms_output.put_line(' Num cursors open is '||ccount);
ccount := 0;
-- get text of open/parsed cursors
for vcur in opencur loop
ccount := ccount + 1;
dbms_output.put_line(' Cursor #'||ccount);
dbms_output.put_line(' text: '|| vcur.sql_text);
end loop;
end;
/
Num cursors open is 144
Cursor #1
text: select priority from resource_mapping_priority$ where attrib
Cursor #2
text: select i.obj#,i.ts#,i.file#,i.block#,i.intcols,i.type#,i.fla
Cursor #3
text: select value, consumer_group from resource_group_mapping$ wh
:
:
:
Cursor #142
text: select col#,intcol#,reftyp,stabid,expctoid from refcon$ wher
Cursor #143
text: table_1_ff_14f_0_0_0
Cursor #144
text: SELECT COUNT(*) FROM V$OPEN_CURSOR
Cursor #145
text: select /*+ index(idl_sb4$ i_idl_sb41) +*/ piece#,length,piec
PL/SQL procedure successfully completed.
-- snippet 2
SQL> select value, name from v$sysstat where statistic# in (2,3);
VALUE NAME
---------- ----------------------------------------------------------------
47767 opened cursors cumulative
41 opened cursors current