错误:PLS-00435:没有BULK In-BIND的DML语句不能在FORALL中使用

时间:2014-08-03 20:30:04

标签: oracle11g

我收到以下错误消息。你能帮我解决一下这个问题。

“错误:PLS-00435:没有BULK In-BIND的DML语句不能在FORALL中使用”

这是我的编码。

  create or replace procedure inst4 is
  var1 varchar2(20);
  type nest is table of coll%rowtype;
  emp1 nest;
  cursor emp2 is select * from coll;
  ex_dml_errors exception;
  l_error_count  NUMBER;
  PRAGMA EXCEPTION_INIT(ex_dml_errors, -24381);
  begin 
  select * BULK COLLECT into emp1 from coll;
  FORALL  i in emp1.FIRST..EMP1.LAST SAVE EXCEPTIONS
  insert into coll values ('Shan',50000);
  insert into coll values('Yan',70000);
  insert into coll values('than',null);
  insert into coll values('unibi',9000);
  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;

1 个答案:

答案 0 :(得分:0)

只有第一个insertforall的一部分,并且它不会使用emp1集合中的一行 - 因此会出错。

部分基于后面的问题,看起来您正在尝试使用四组值填充集合,然后使用它来执行批量插入;所以与您目前从批量选择中填充的集合无关:

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;
/

然后执行时:

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 

另一种方法是单独执行每个插入,效率较低,并使用异常处理程序将每个插入包装在自己的块中:

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;
/

然后,当执行该过程时,插入相同的三个记录,输出为:

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

您也可以使用the built-in error logging mechanism,这意味着您不需要使用任何PL / SQL;但也意味着你必须能够创建错误记录表。

如果您正在控制您尝试插入的数据,我不确定为什么您甚至会尝试插入一个您知道无效的值。