Error: PLS-00435: DML statement without BULK In-BIND cannot be used inside FORALL

前端 未结 1 1441
北荒
北荒 2021-01-26 16:21

I am getting the below error message. Can you please help me to sort out this problem.

\"Error: PLS-00435: DML statement without BULK In-BIND cannot be used inside FORAL

相关标签:
1条回答
  • 2021-01-26 17:11

    Only the first insert is part of the forall, and it doesn't use a row from the emp1 collection - hence the error.

    Based partly on a later question, it looks like you're trying to populate a collection with four sets of values and then use that to perform a bulk insert; so nothing to do with the collection you're currently populating from the bulk select:

    create table maav (id varchar2(10), sal number not null);
    
    create or replace procedure bulk_ins is
      type t_maav_rows is table of maav%rowtype;
      l_maav_rows t_maav_rows;
      l_error_count  number;
      ex_dml_errors exception;
      pragma exception_init(ex_dml_errors, -24381);
    begin
      l_maav_rows := t_maav_rows();
      l_maav_rows.extend(4);
      l_maav_rows(1).id := 'Shan';
      l_maav_rows(1).sal := 50000;
      l_maav_rows(2).id := 'Yan';
      l_maav_rows(2).sal := 70000;
      l_maav_rows(3).id := 'than';
      l_maav_rows(3).sal := null;
      l_maav_rows(4).id := 'unibi';
      l_maav_rows(4).sal := 9000;
    
      forall i in l_maav_rows.first..l_maav_rows.last save exceptions
        insert into maav values l_maav_rows(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;
    /
    

    Then when that is executed:

    exec bulk_ins;
    
    anonymous block completed
    Number of failures: 1
    Error: 1 Array Index: 3 Message: ORA-01400: cannot insert NULL into ()
    
    select * from maav;
    
    ID                SAL
    ---------- ----------
    Shan            50000 
    Yan             70000 
    unibi            9000 
    

    Another way is to do each insert individually, which is less efficient, and to wrap each in its own block with an exception handler:

    create or replace procedure bulk_ins is
      null_ex exception;
      pragma exception_init (null_ex, -1400);
    begin
      for r in (
        select 'Shan' as id, 50000 as sal from dual
        union all select 'Yan', 70000 from dual
        union all select 'than', null from dual
        union all select 'ubini', 9000 from dual
      )
      loop
        begin
          insert into maav (id, sal) values (r.id, r.sal);
        exception
          when null_ex then
            dbms_output.put_line('Error: ' || sqlerrm);
        end;
      end loop;
    end;
    /
    

    Then when the procedure is executed the same three records are inserted, and the output is:

    anonymous block completed
    Error: ORA-01400: cannot insert NULL into ("SCHEMA"."MAAV"."SAL")
    

    You could also use the built-in error logging mechanism which would mean you didn't need to use any PL/SQL; but would also mean you have to be able to create the error logging table.

    If you're controlling the data you're trying to insert I'm not really sure why you'd even attempt to insert a value you know isn't valid.

    0 讨论(0)
提交回复
热议问题