Cursor Attributes for FORALL
You can use cursor attributes after you execute a FORALL statement to get information about the DML operation run within FORALL. Oracle also offers an additional attribute, %BULK_ROWCOUNT, to give you more granular information about the results of the bulk DML statement.
Table 13-2 describes the significance of the values returned by these attributes for FORALL.
Table 13-2. Implicit SQL cursor attributes for DML statements | |
Name | Description |
SQL%FOUND | Returns TRUE if the last execution of the SQL statement modified one or more rows. |
SQL%NOTFOUND | Returns TRUE if the last execution of the SQL statement modified one or more rows. |
SQL%ROWCOUNT | Returns the total number of rows processed by all executions of the SQL statement, not just the last statement. |
SQL%ISOPEN | Always returns FALSE and should not be used. |
SQL%BULK_ROWCOUNT | Returns a collection that tells you the number of rows processed by each corresponding SQL statement executed via FORALL. Note: when %BULK_ROWCOUNT(i) is zero, %FOUND and %NOTFOUND are FALSE and TRUE, respectively. |
Let's now explore the %BULK_ROWCOUNT composite attribute. This attribute, designed specifically for use with FORALL, has the semantics of (acts like) an associative array or collection. Oracle deposits in the Nth element in this collection the number of rows processed by the Nth execution of the FORALL's INSERT, UPDATE, or DELETE. If no rows were affected, the Nth row will contain a zero value.
Here is an example of using %BULK_ROWCOUNT (and the overall %ROWCOUNT attribute as well):
DECLARE TYPE isbn_list IS TABLE OF VARCHAR2(13); my_books isbn_list := isbn_list ( '1-56592-375-8', '0-596-00121-5', '1-56592-849-0', '1-56592-335-9', '1-56592-674-9', '1-56592-675-7', '0-596-00180-0', '1-56592-457-6' );BEGIN FORALL book_index IN my_books.FIRST..my_books.LAST UPDATE books SET page_count WHERE isbn = my_books (book_index); -- Did I update the total number of books I expected? IF SQL%ROWCOUNT != 8 THEN DBMS_OUTPUT.PUT_LINE ( 'We are missing a book!'); END IF; -- Did the 4th UPDATE statement affect any rows? IF SQL%BULK_ROWCOUNT(4) = 0 THEN DBMS_OUTPUT.PUT_LINE ( 'What happened to Oracle PL/SQL Programming?');; END IF;END;Here are some tips on how this attribute works:
· The FORALL statement and %BULK_ROWCOUNT use the same subscripts or row numbers in the collections. For example, if the collection passed to FORALL has data in rows 10 through 200, then the %BULK_ROWCOUNT pseudo-collection will also have rows 10 through 200 defined and populated. Any other rows will be undefined.
· When the INSERT affects only a single row (when you specify a VALUES list, for example), a row's value in %BULK_ROWCOUNT will be equal to 1. For INSERT...SELECT statements, however, %BULK_ROWCOUNT can be greater than 1.
· The value in a row of the %BULK_ROWCOUNT pseudo-array for deletes and inserts may be any natural number (0 or positive); these statements can modify more than one row, depending on their WHERE clauses.