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
- How to Use Explicit Cursors in PL/SQL (Oracle Database 23ai)
- How to Fix ORA-01403: No Data Found in Oracle PL/SQL
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.
