Wednesday, 31 May 2017

undefined undefined

SAVE EXCEPTIONS and SQL%BULK_EXCEPTION


We saw how the FORALL syntax allows us to perform bulk DML operations.

 But what happens if one of those individual operations results in an exception? If there is no exception handler, all the work done by the current bulk operation is rolled back. 

If there is an exception handler, the work done prior to the exception is kept, but no more processing is done. 

So instead we should use the SAVE EXCEPTIONS clause to capture the exceptions and allow us to continue past them. 

We can subsequently look at the exceptions by referencing the SQL%BULK_EXCEPTION cursor attribute. 

create the following table.


CREATE TABLE exception_test (
  id  NUMBER(10) NOT NULL
);

The following code creates a collection with 100 rows, but sets the value of rows 50 and 51 to NULL. 

Since the above table does not allow nulls, these rows will result in an exception. 

The SAVE EXCEPTIONS clause allows the bulk operation to continue past any exceptions, but if any exceptions were raised in the whole operation, it will jump to the exception handler once the operation is complete. 

In this case, the exception handler just loops through the SQL%BULK_EXCEPTION cursor attribute to see what errors occurred.

SET SERVEROUTPUT ON
DECLARE
  TYPE t_tab IS TABLE OF exception_test%ROWTYPE;

  l_tab          t_tab := t_tab();
  l_error_count  NUMBER;
  
  ex_dml_errors EXCEPTION;
  PRAGMA EXCEPTION_INIT(ex_dml_errors, -24381);
BEGIN
  -- Fill the collection.
  FOR i IN 1 .. 100 LOOP
    l_tab.extend;
    l_tab(l_tab.last).id := i;
  END LOOP;

  -- Cause a failure.
  l_tab(50).id := NULL;
  l_tab(51).id := NULL;
  
  EXECUTE IMMEDIATE 'TRUNCATE TABLE exception_test';

  -- Perform a bulk operation.
  BEGIN
    FORALL i IN l_tab.first .. l_tab.last SAVE EXCEPTIONS
      INSERT INTO exception_test
      VALUES l_tab(i);
  EXCEPTION
    WHEN ex_dml_errors THEN
      l_error_count := SQL%BULK_EXCEPTIONS.count;
      DBMS_OUTPUT.put_line('Number of failures: ' || l_error_count);
      FOR i IN 1 .. l_error_count LOOP
        DBMS_OUTPUT.put_line('Error: ' || i || 
          ' Array Index: ' || SQL%BULK_EXCEPTIONS(i).error_index ||
          ' Message: ' || SQLERRM(-SQL%BULK_EXCEPTIONS(i).ERROR_CODE));
      END LOOP;
  END;
END;
/

Number of failures: 2
Error: 1 Array Index: 50 Message: ORA-01400: cannot insert NULL into ()
Error: 2 Array Index: 51 Message: ORA-01400: cannot insert NULL into ()

PL/SQL procedure successfully completed.

SQL>

As expected the errors were trapped. If we query the table we can see that 98 rows were inserted correctly.


SELECT COUNT(*)
FROM   exception_test;

  COUNT(*)
----------
98

1 row selected.

SQL>

Related Posts:

  • ORACLE-FORU - Oracle FORALL Function in Bulk Collection. FORALL in Bulk Collection. The FORALL syntax allows us to bind the contents of a collection to a single DML statement, allowing the DML to be run for each row in the collection without requiring a context switch e… Read More
  • ORACLE-FORU - How to handle Exception in Bulk Collection Method. SAVE EXCEPTIONS and SQL%BULK_EXCEPTION We saw how the FORALL syntax allows us to perform bulk DML operations.  But what happens if one of those individual operations results in an exception? If there is… Read More
  • ORACLE-FORU - SQL%BULK_ROWCOUNT SQL%BULK_ROWCOUNT The SQL%BULK_ROWCOUNT cursor attribute gives granular information about the rows affected by each iteration of the FORALL statement. Every row in the driving collection has a corresponding row in the SQ… Read More
  • ORACLE-FORU - ORACLE DBMS_PROFILER DBMS_PROFILER The DBMS_PROFILER package was introduced in Oracle 8i to allow developers to profile the run-time behaviour of PL/SQL code,  Making it easier to identify performance bottlenecks which can then… Read More
  • Utility / Math related queries Utility / Math related queries Convert number to words More info: Converting number into words in Oracle SELECT TO_CHAR (TO_DATE (1526, 'j'), 'jsp') FROM DUAL; Output: one thousand five hundred twenty-six Find st… Read More

2 comments:

Copyright © 2025 ORACLE-FORU - SQL, PL/SQL and ORACLE D2K(FORMS AND REPORTS) collections | Powered by Blogger
Design by N.Design Studio | Blogger Theme by NewBloggerThemes.com