Forum OpenACS Q&A: Response to something like vacuum analyze or compact database for Oracle?

Sebastiano, according to the Oracle PL/SQL documentation, Oracle only identifies the rows the meet the criteria when the OPEN is executed, it does not retrieve them until the FETCH. In the example above, the OPEN is performed, then the same rows are deleted and committed. Where is the FETCH getting its data?

The following sample highlights that the retrieval of data is only done at the FETCH:

SQL> set serveroutput on size 1000000
SQL> DECLARE
  2   CURSOR v_cur IS
  3    SELECT name FROM all_source;
  4   v_rec v_cur%ROWTYPE;
  5   v_rowcount NUMBER DEFAULT 0;
  6  BEGIN
  7   dbms_output.put_line( 'Start time: ' || to_char(sysdate,'hh24:mi:ss') );
  8   OPEN v_cur;
  9   dbms_output.put_line( 'After OPEN: ' || to_char(sysdate,'hh24:mi:ss') );
 10  
 11   LOOP
 12    FETCH v_cur INTO v_rec;
 13    IF v_cur%NOTFOUND THEN
 14     EXIT;
 15    END IF;
 16    v_rowcount := v_rowcount + 1;
 17   END LOOP;
 18  
 19   dbms_output.put_line( 'After FETCHes: ' || to_char(sysdate,'hh24:mi:ss') );
 20  
 21   CLOSE v_cur;
 22  
 23   dbms_output.put_line( 'After CLOSE: ' || to_char(sysdate,'hh24:mi:ss') );
 24   dbms_output.put_line( 'Rows retrieved: ' || to_char( v_rowcount ) );
 25  
 26  END;
 27  /
Start time: 08:56:14
After OPEN: 08:56:14
After FETCHes: 08:56:46
After CLOSE: 08:56:46
Rows retrieved: 52517

PL/SQL procedure successfully completed.

In this case, Oracle identified the rows at the OPEN, but didn't retrieve them. The DELETE/COMMIT removed them from the database. Yet the FETCH is able to retrieve rows that no longer exist. The timings highlight where the work is being done. There's no way OPEN could move 50,000+ rows in about a second (not on my system, anyway).

To quote from the Oracle docs: "Rows in the result set are not retrieved when the OPEN statement is executed. Rather, the FETCH statement retrieves the rows."