In Finacle, sometimes users are facing "The resource is busy" error due to the oracle error generated in back-end as "Maximum open cursors exceeded". Not that this error comes often, but we want to take precautionary measures and that is why we are trying to generate an alert for the Finacle engineers i.e. for ourselves so that whenever the maximum no of cursors exceeds for some DB object, we can get the alert. For that, we need to know what is the command to know how many cursors are open for the DB objects at a given time. Can somebody guide us on this matter please.
Another thing to clear my concept, does Oracle use any default cursor for querying a table? Because, my guess is this error is generating because number of users for this software has increased and there are lots of sessions getting opened for the same DB object with select and update query and that is how number of open cursors is getting increased.
I guess you don't close your cursors after you use it, For example, I customized the open_cursor
parameter to allow user to have only one opened cursor (3 cursors oracle uses for its own needs):
SQL> conn / as sysdba
Connected.
SQL> alter system set open_cursors=4 scope=memory
2 /
System altered.
SQL> conn hr/hr
Connected.
SQL> var l_cursor refcursor;
SQL> ed
Wrote file afiedt.buf
1 begin
2 open :l_cursor for select 1 from dual;
3* end;
SQL> /
PL/SQL procedure successfully completed.
SQL> var l_cursor1 refcursor;
SQL> ed
Wrote file afiedt.buf
1 begin
2 open :l_cursor1 for select 1 from dual;
3* end;
SQL> /
begin
*
ERROR at line 1:
ORA-01000: maximum open cursors exceeded
As you see I face the same error you had. Let's close the l_cursor
cursor (the print command displays a cursor's content and closes it) and then open l_cursor1
once again:
SQL> print l_cursor
1
----------
1
SQL> ed
Wrote file afiedt.buf
1 begin
2 open :l_cursor1 for select 1 from dual;
3* end;
SQL> /
PL/SQL procedure successfully completed.
SQL> print l_cursor1
1
----------
1
As you can see Oracle can successfully open the l_cursor1
cursor.
As a quick solution of your problem you can increase the open_cursor
parameter with command (you system might need additional resources to keep the current performance):
alter system set open_cursors=800 scope=both
I used scope=memory
, because I want this demo doesn't affect my system after the database server is restarted. You have to specify scope=both to persist this parameter in spfile
. But I guess you have to exam your system and find out if you have opened cursors that aren't used anymore.
Your guess about "does Oracle use any default cursor for querying a table?" is true, Oracle uses cursors to query tables, you can make sure:
SQL> var l_cursor refcursor;
SQL> ed
Wrote file afiedt.buf
1 begin
2 open :l_cursor for select 1 from dual;
3* end;
SQL> /
PL/SQL procedure successfully completed.
SQL> select * from employees;
select * from employees
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-01000: maximum open cursors exceeded
SQL> print l_cursor
1
----------
1
SQL> select * from employees;
EMPLOYEE_ID FIRST_NAME LAST_NAME
----------- -------------------- -------------------------
EMAIL PHONE_NUMBER HIRE_DAT JOB_ID SALARY
------------------------- -------------------- -------- ---------- ----------
COMMISSION_PCT MANAGER_ID DEPARTMENT_ID
-------------- ---------- -------------
205 Shelley Higgins
...
To get all opened cursors check this answer