How to Fix ORA-06511: PL/SQL: Cursor Already Open in Oracle

Avoid opening an explicit cursor twice by checking %ISOPEN, closing cursors after errors, or using cursor FOR loops.

ORA-06511 is raised when PL/SQL code opens an explicit cursor that is already open. It is raised as the predefined exception CURSOR_ALREADY_OPEN, typically from an OPEN inside a loop, or from a second run of code whose cursor was not closed after an earlier pass or an error. Close the cursor before opening it again, or use a cursor FOR loop, which opens and closes it for you.

Reproduce the Error

Example:

create table demo_flights (flight_no varchar2(8), status varchar2(10));
insert into demo_flights values ('NA101', 'ON TIME');
insert into demo_flights values ('NA202', 'DELAYED');
commit;
declare
  cursor c_flights is select flight_no from demo_flights;
begin
  open c_flights;
  open c_flights;
end;
/

Output:

Table DEMO_FLIGHTS created.

1 row inserted.

1 row inserted.

Commit complete.

declare
*
ERROR at line 1:
ORA-06511: PL/SQL: cursor already open
ORA-06512: at line 2
ORA-06512: at line 5

The stack points to line 5, the second OPEN, and to line 2, where the cursor is declared.

Fix: Check %ISOPEN, or Use a FOR Loop

Example:

set serveroutput on
declare
  cursor c_flights is select flight_no from demo_flights;
begin
  open c_flights;
  -- reopen safely: close first if it is open
  if c_flights%isopen then
    close c_flights;
  end if;
  open c_flights;
  close c_flights;

  -- or let a cursor FOR loop open and close it
  for r in c_flights loop
    dbms_output.put_line(r.flight_no);
  end loop;
end;
/

Output:

NA101
NA202

PL/SQL procedure successfully completed.

Things to Know

  • Cursors declared in a package stay open between calls in the same session, so a missing CLOSE shows up on the next call.
  • Close cursors in exception handlers as well, when %ISOPEN is true, so an error does not leave them open.
  • Cursor variables (SYS_REFCURSOR) can be opened again without closing; OPEN FOR closes the previous query first.

Related Guides

Conclusion

ORA-06511 means OPEN was called on a cursor that is still open. Check %ISOPEN and close it first, close cursors in exception handlers, or let a cursor FOR loop manage it.

Vinish Kapoor
Vinish Kapoor

An Oracle ACE, author of four books on Oracle APEX, SQL and PL/SQL, and Oracle Forms, and a software developer building Oracle database applications since 2001.

guest

0 Comments
Oldest
Newest Most Voted