Oracle 中带有 BULK_EXCEPTIONS 的真实错误文本

Real error text with BULK_EXCEPTIONS in Oracle

使用

时是否有可能知道真正的原因,真正的ora代码(在这种情况下违反唯一键)
    FORALL var_i_idx IN 1..table_of_t.count SAVE EXCEPTIONS
    INSERT INTO TABLE_A VALUES (                          
        table_of_t(var_i_idx).var_id);
        RETURN retVal;
        EXCEPTION
           WHEN OTHERS
           THEN
              IF SQLCODE = -24381
              THEN
                 FOR var_i_idx IN 1 .. SQL%BULK_EXCEPTIONS.COUNT
                 LOOP
                 v_action := 'Insert table_of_t';
                 v_error_text := 'Unexcpected exception SQLCODE: ' || SQL%BULK_EXCEPTIONS (var_i_idx).ERROR_INDEX || ' -- ERROR:' || sqlerrm(SQL%BULK_EXCEPTIONS (var_i_idx).ERROR_CODE);
dbms_output.put_line('Unexcpected exception SQLCODE: '||SQLCODE||' -- ERROR: '||SQLERRM);

DBMS 将打印以下内容:意外异常 SQLCODE:-24381 -- 错误:ORA-24381:数组 DML 中有错误

但是有可能知道真正的原因吗?

是的,您可以获得实际的错误消息,尽管只是基本消息。您遇到的问题是您的 dbms_output 消息是针对批量错误而不是单个项目错误。您从 SQL%BULK_EXCEPTIONS 集合中的 ERROR_CODE 得到项目错误。您甚至可以通过 ERROR_INDEX 访问导致异常的实际数据。这索引了在 forall 语句中命名的集合中的条目。错误消息和批量集合的骨架访问(其中 blk_array 是 forall 中使用的集合的名称)。参见 fiddle

for err_idx in 1 .. sql%bulk_exceptions
loop     
    msg := sqlerrm(-sql%bulk_exceptions(err_idx).error_code);   
    val := blk_array(sql%bulk_exceptions(err_idx).error_index);
end loop; 

在 fiddle 中忽略设置 FORALL 的代码,它完全可用于另一个任务。只关注例外部分,除了以下几行:

declare
    errors_during_forall exception;                       -- create name for errors during bulk, forall, processing
    pragma exception_init (errors_during_forall, -24381); -- and tie that name to the actual Oracle error number

这允许您为异常定义一个名称,然后在异常部分引用该名称。