Solved

ORA-06511 PL/SQL: cursor already open

Posted on 2002-06-17
6
3,413 Views
Last Modified: 2012-05-04
Hi all,

Why doesn't the following code return ORA-06511 as I would have expected?

Thanks.

CREATE TABLE blah (col1 NUMBER);

DECLARE
   PROCEDURE do_something IS
      CURSOR c IS
         SELECT *
           FROM blah;
     
      r c%ROWTYPE;
   BEGIN
      OPEN c;
      FETCH c INTO r;
      IF (r.col1 != 50)
      THEN
         RETURN;
      END IF;
   END do_something;
   
BEGIN
   EXECUTE IMMEDIATE 'TRUNCATE TABLE blah';
   FOR i IN 1..5
   LOOP
      INSERT INTO blah
      VALUES (i);
   END LOOP;
   COMMIT;
   FOR i IN 1..10
   LOOP
      do_something;
   END LOOP;
END;
/

DROP TABLE blah;
0
Comment
Question by:Kong
  • 3
  • 2
6 Comments
 
LVL 3

Expert Comment

by:mnicoras
ID: 7084685
Hi,

try this and probably it will tell you more:

CREATE TABLE blah (col1 NUMBER);

SET SERVEROUTPUT ON;

DECLARE
  PROCEDURE do_something IS
     CURSOR c IS
        SELECT *
          FROM blah;
     r c%ROWTYPE;
  BEGIN
-- the part I add
     if c%isopen then
       dbms_output.put_line('cursor is open? '||'true');
     else
       dbms_output.put_line('cursor is open? '||'false');
     end if;
-- the part I add
     OPEN c;
     FETCH c INTO r;
     IF (r.col1 != 50)
     THEN
        RETURN;
     END IF;
  END do_something;
BEGIN
  EXECUTE IMMEDIATE 'TRUNCATE TABLE blah';
  FOR i IN 1..5
  LOOP
     INSERT INTO blah
     VALUES (i);
  END LOOP;
  COMMIT;
  FOR i IN 1..10
  LOOP
     do_something;
  END LOOP;
END;
/

DROP TABLE blah;


enjoy,
Marius Nicoras
0
 
LVL 3

Expert Comment

by:mnicoras
ID: 7084687
Hi,

and now try this:

CREATE TABLE blah (col1 NUMBER);

SET SERVEROUTPUT ON;

DECLARE
  PROCEDURE do_something IS
     CURSOR c IS
        SELECT *
          FROM blah;
     r c%ROWTYPE;
  BEGIN
-- the part I add
     if c%isopen then
       dbms_output.put_line('cursor is open? '||'true');
     else
       dbms_output.put_line('cursor is open? '||'false');
     end if;
-- the part I add
     OPEN c;
     FETCH c INTO r;
-- the part I add more
     if c%isopen then
       dbms_output.put_line('cursor is open? '||'true');
     else
       dbms_output.put_line('cursor is open? '||'false');
     end if;
     OPEN c;
     FETCH c INTO r;
-- the part I add more
     IF (r.col1 != 50)
     THEN
        RETURN;
     END IF;
  END do_something;
BEGIN
  EXECUTE IMMEDIATE 'TRUNCATE TABLE blah';
  FOR i IN 1..5
  LOOP
     INSERT INTO blah
     VALUES (i);
  END LOOP;
  COMMIT;
  FOR i IN 1..10
  LOOP
     do_something;
  END LOOP;
END;
/

DROP TABLE blah;

enjoy more,
Marius Nicoras
0
 
LVL 2

Author Comment

by:Kong
ID: 7084760
Thanks Marius,

You're trying to Open, Fetch, Open within the same scope - which results in ORA-6511, that's expected.

I think I've just explained my own question 8-/ is it possible that we're talking about scope here: since the cursor is opened within a subprogram, when that subprogram exits the cursor goes out of scope/is dereferenced and hence garbage collected. The next time OPEN is called, it has been 'implicitly' closed, thus the exception is not raised.

What do you think?

Here's a supporting example, where the cursor is still within the scope of the subprogram, thus raising the exception:

CREATE TABLE blah (col1 NUMBER);

DECLARE
  CURSOR c IS
     SELECT *
       FROM blah;
       
  r c%ROWTYPE;      

  PROCEDURE do_something IS
  BEGIN
     OPEN c;
     FETCH c INTO r;
     IF (r.col1 != 50)
     THEN
        RETURN;
     END IF;
  END do_something;
 
BEGIN
  EXECUTE IMMEDIATE 'TRUNCATE TABLE blah';
  FOR i IN 1..5
  LOOP
     INSERT INTO blah
     VALUES (i);
  END LOOP;
  COMMIT;
  OPEN c;
  FETCH c INTO r;
  FOR i IN 1..10
  LOOP
     do_something;
  END LOOP;
END;
/

DROP TABLE blah;
0
PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

 
LVL 47

Expert Comment

by:schwertner
ID: 7085892
Open the cursor with this the code:

IF c%ISOPEN
  CLOSE c;
END IF;
  OPEN c;
0
 
LVL 3

Accepted Solution

by:
mnicoras earned 100 total points
ID: 7089505
Hi,

you have figure out exactly the idea for opened cursors.

it's a different context for cursor when sub-program it's closed. IN your last example the cursor is within the same context of the sub-program's.

Good for you that you understood correctly the problem. "schwertner" suggestion is obvious! you should not forget it, but I think you already know that, otherwise you didn't come-up with this issue.

best regards,
Marius Nicoras
0
 
LVL 2

Author Comment

by:Kong
ID: 7091348
Well done guys, thanks for your help too schwertner.
0

Featured Post

PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

Join & Write a Comment

Working with Network Access Control Lists in Oracle 11g (part 1) Part 2: http://www.e-e.com/A_9074.html So, you upgraded to a shiny new 11g database and all of a sudden every program that used UTL_MAIL, UTL_SMTP, UTL_TCP, UTL_HTTP or any oth…
Using SQL Scripts we can save all the SQL queries as files that we use very frequently on our database later point of time. This is one of the feature present under SQL Workshop in Oracle Application Express.
This video shows how to set up a shell script to accept a positional parameter when called, pass that to a SQL script, accept the output from the statement back and then manipulate it in the Shell.
This video shows syntax for various backup options while discussing how the different basic backup types work.  It explains how to take full backups, incremental level 0 backups, incremental level 1 backups in both differential and cumulative mode a…

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now