代码之家  ›  专栏  ›  技术社区  ›  FrustratedWithFormsDesigner

Oracle DML错误缺少详细信息

  •  3
  • FrustratedWithFormsDesigner  · 技术社区  · 14 年前

    我正在从这样的大容量插入操作中捕获错误:

    begin
        --bulk insert
        forall i in v_data.first .. v_data.last save exceptions
            insert into my_filter_table values v_data (i);
    
        commit;
    
    exception
        -- catch and print the saved-up DML errors.
        when X_DML_ERRORS then
            declare
                v_iteration number;
            begin
                dbms_output.put_line('');
                dbms_output.put_line('DML Errors:');
                for i in 1 .. SQL%BULK_EXCEPTIONS.count loop
                    v_iteration := SQL%BULK_EXCEPTIONS(i).error_index;
    
                    dbms_output.put_line('Iteration: '||v_iteration||' Message: '||
                                     SQLERRM(-SQL%BULK_EXCEPTIONS(i).ERROR_CODE));
    
    
                end loop;
            end;
    end;
    

    输出如下所示:

        Iteration: 3 Message: ORA-01400: cannot insert NULL into ()
        Iteration: 4 Message: ORA-02290: check constraint (.) violated
        Iteration: 8 Message: ORA-00001: unique constraint (.) violated
    

    我得到错误的事实并不困扰我,因为我正在测试错误处理代码。问题是Oracle错误消息没有显示约束名,即它显示 check constraint (.) violated 但这并不能告诉我违反了哪个检查约束。

    有人知道这是怎么回事吗?

    (Oracle版本10.2)

    1 回复  |  直到 13 年前
        1
  •  6
  •   Daniel Emge    14 年前

    SQL%批量异常(I)。错误代码只保存Oracle错误号。然后使用sqlerm函数查找错误消息文本。这个函数将无法知道什么约束被打破。

    您可以调用sqlerm函数,而不会引发异常来复制结果。

    begin
       dbms_output.put_Line(sqlerrm(-1400));
       dbms_output.put_Line(sqlerrm(-2290));
       dbms_output.put_Line(sqlerrm(-1));
    end;
    

    哪些输出

    ORA-01400: cannot insert NULL into ()
    ORA-02290: check constraint (.) violated
    ORA-00001: unique constraint (.) violated
    

    可能的解决方法是在异常处理程序中重新执行失败的语句。

    表DEF:

    create table t ( x number(1) primary key);
    

    代码:

    declare
       dml_errors EXCEPTION;
       PRAGMA EXCEPTION_INIT(dml_errors, -24381);
       TYPE t_nums is table of NUMBER;
       l_nums t_nums := t_nums(1,1,10);
    begin
       forall i in 1..l_nums.count save exceptions
          execute immediate 'insert into t values (:x)' using l_nums(i);
    exception
       when dml_errors then
          for j in 1..sql%bulk_exceptions.count
          loop
             if sql%bulk_exceptions(j).error_code = 1
             then
                begin
                   execute immediate 'insert into t values (:x)'
                      using l_nums(sql%bulk_exceptions(j).error_index);
                exception
                   when dup_val_on_index then
                      dbms_output.put_line(sqlerrm);
                end;
             else
                dbms_output.put_line(sqlerrm(-sql%bulk_exceptions(j).error_code));
             end if;
          end loop;
    end;
    

    输出:

    ORA-01438: value larger than specified precision allowed for this column
    ORA-00001: unique constraint (XXXXXXXX.SYS_C00264470) violated
    ORA-24381: error(s) in array DML
    
    推荐文章