Continuation of first cursor example

This is an example of a cursor with parameters. The open statement passes parameter values to the cursor that will be used in the query when it is executed. For each parameter you define in the cursor there must be an actual parameter in the OPEN statement to correspond to it. The select statement used with a parameter does not have the into clause. In the code below the SET SERVEROUTPUT ON/OFF is used so that the dbms line can be used to convey what is happening. The program has 5 variables to hold data. There is also a cursor which takes a driveno and drivename from the drive table. The order is by driveno. The second cursor is the donation cursor which is set up with the parameter v_drive_no which is defined as a NUMBER. The select is taking the contamt from the donation table where the v_drive_no which has been converted to character with driveno which was defined as character.

In the loop the drive cursor was opened. Then the loop is entered which fetches from the cursor. It then goes through the open/close IF described in the previous example. Next the total accumulator is initialized to 0.

Now the donation_cursor is opened and with the open the numeric conversion of the parameter v_current_drive_no (which was gotton from the fetch to the drive_cursor ) is passed to the donation_cursor where it has the name v_drive_no. We now add to the total accumulator and display the dbms line. At the end of the inner loop, the total is written to a new table, the donation_cursor is closed and control returns to the outer cursor which gets the next driveno and drivename. More detailed analysis of the logic is included with the original version.

PL/SQL CODE:

SET SERVEROUTPUT ON
DECLARE
  
  v_current_drive_no   drive.driveno%TYPE;
  v_drive_name         drive.drivename%TYPE;
  v_contamt            donation.contamt%TYPE;
  v_tot_contamt        cont_info.contamt%TYPE;
  CURSOR drive_cursor IS
     SELECT driveno, drivename FROM drive
     ORDER BY driveno;
  CURSOR donation_cursor(v_drive_no   NUMBER) IS
     SELECT contamt FROM donation 
     WHERE TO_CHAR(v_drive_no) = driveno
     ORDER BY driveno;
  BEGIN
     OPEN drive_cursor;
     LOOP
       FETCH drive_cursor INTO v_current_drive_no, v_drive_name;
       EXIT WHEN drive_cursor%NOTFOUND;
       IF donation_cursor%ISOPEN THEN
         CLOSE donation_cursor;
       END IF;
       v_tot_contamt := 0;
      
       OPEN donation_cursor (TO_NUMBER(v_current_drive_no));
       LOOP
         FETCH donation_cursor INTO v_contamt;
         EXIT WHEN donation_cursor%NOTFOUND;
         v_tot_contamt := v_tot_contamt + v_contamt;
         dbms_output.put_line('The current amount is: '||v_tot_contamt);
       END LOOP;
       INSERT into cont_info 
          VALUES(v_current_drive_no, v_drive_name, v_tot_contamt);
       CLOSE donation_cursor;
     END LOOP;
     CLOSE drive_cursor;
END;
/
SET SERVEROUTPUT OFF

SQL CODE:

SQL> @ cursor7a2
The current amount is: 25
The current amount is: 45
The current amount is: 55
The current amount is: 105
The current amount is: 40
The current amount is: 75
The current amount is: 10
The current amount is: 20

PL/SQL procedure successfully completed.

Input truncated to 20 characters
SQL> SELECT * FROM cont_info;

DRI DRIVENAME         CONTAMT
--- --------------- ---------
100 Kids Shelter          105
200 Animal Home            75
300 Health Aid             20
400 Half Way                0

The next version of this program uses the WHILE loop instead of the LOOP with the exit. The logic here has the initializing fetch outside the loop and the fetch that handles all other records from the cursor at the bottom of the loop, right before the END LOOP.

SQL CODE:

SET SERVEROUTPUT ON
DECLARE
  v_drive_no      drive.driveno%TYPE;
  v_drive_name    drive.drivename%TYPE;
  v_contamt       donation.contamt%TYPE;
  v_tot_contamt   cont_info.contamt%TYPE;
  CURSOR drive_cursor IS
     SELECT driveno, drivename FROM drive
     ORDER BY driveno;
  CURSOR donation_cursor IS
     SELECT contamt FROM donation 
     WHERE v_drive_no = driveno
     ORDER BY driveno;
  BEGIN
     OPEN drive_cursor;
     FETCH drive_cursor INTO v_drive_no, v_drive_name;
     WHILE drive_cursor%FOUND LOOP
       IF donation_cursor%ISOPEN THEN
         CLOSE donation_cursor;
       END IF;
       OPEN donation_cursor;
       v_tot_contamt := 0;
       FETCH donation_cursor INTO v_contamt;
       WHILE donation_cursor%FOUND LOOP
         v_tot_contamt := v_tot_contamt + v_contamt;
         dbms_output.put_line('The current amount is: '||v_tot_contamt);
         FETCH donation_cursor INTO v_contamt;
       END LOOP;
       INSERT into cont_info 
          VALUES(v_drive_no, v_drive_name, v_tot_contamt);
       CLOSE donation_cursor;
       FETCH drive_cursor INTO v_drive_no, v_drive_name;
     END LOOP;
     CLOSE drive_cursor;
END;
/
SET SERVEROUTPUT OFF

SQL CODE:

SQL> @ cursor7b
The current amount is: 25
The current amount is: 45
The current amount is: 55
The current amount is: 105
The current amount is: 40
The current amount is: 75
The current amount is: 10
The current amount is: 20

PL/SQL procedure successfully completed.

Input truncated to 20 characters
SQL> SELECT * FROM cont_info;

DRI DRIVENAME         CONTAMT
--- --------------- ---------
100 Kids Shelter          105
200 Animal Home            75
300 Health Aid             20
400 Half Way                0