【问题标题】:Trying to get the actual data that cause an exception试图获取导致异常的实际数据
【发布时间】:2017-10-08 07:59:48
【问题描述】:

我有一个过程,它接受 2 个关联数组的输入,经过一些基本计数检查后,执行 FORALL 语句将数据插入到表中。

程序如下:

    PROCEDURE   INSERT_RECS(P_PROD_TYP IN prod_type, P_PROD_ADD_PK IN prod_pk_type) 
        IS

        uniq_key EXCEPTION;
        PRAGMA EXCEPTION_INIT(uniq_key, -00001);
        loc_cnt  NUMBER;

        BEGIN
            IF P_PROD_TYP.COUNT = P_PROD_ADD_PK.COUNT THEN
               FORALL i IN P_PROD_TYP.FIRST .. P_PROD_TYP.LAST
                INSERT INTO product_table ( pk, 
                                            id,
                                            created_by,
                                            created_on,
                                            last_chg_by, 
                                            last_chg_on)
                                    VALUES (P_PROD_ADD_PK(i),
                                            P_PROD_TYP(i).id,
                                            P_PROD_TYP(i).created_by,
                                            P_PROD_TYP(i).created_on,
                                            NULL,
                                            NULL);

            END IF;
        EXCEPTION
            WHEN uniq_key THEN
                loc_cnt := SQL%BULK_EXCEPTIONS.count;
                FOR i IN 1 .. loc_cnt LOOP
                    dbms_output.put_line('EXCEPTION: Array Index: ' || SQL%BULK_EXCEPTIONS(i).error_index ||
                            ' Message: ' || SQLERRM(-SQL%BULK_EXCEPTIONS(i).ERROR_CODE) || 
                            ' SQLERRM: ' || SQLERRM || 
                            ' SQLCODE: ' || SQLCODE ||    
                            ' stack: ' || SYS.dbms_utility.format_call_stack);
                END LOOP;    
                RETURN;
        END;

我想要的是,如果我遇到异常,有没有办法可以查看导致问题的记录,基本上是关联数组中的索引,或者至少让 SQL% 信息有信息.

我看过以下内容: http://www.dba-oracle.com/plsql/t_plsql_exceptions.htm

但这会输出有关该列的信息,但这不是我想要的。

【问题讨论】:

  • 既然你有索引 (SQL%BULK_EXCEPTIONS(i).error_index ),为什么不直接遍历 p_prod_typ 直到找到导致错误的记录的索引?

标签: oracle exception plsql associative-array


【解决方案1】:

不确定是否真的回答了您的查询,但您可以使用异常块中的循环变量 i 在您的情况下显示异常数组的内容。请参阅下面的示例过程:

CREATE OR REPLACE PROCEDURE PROC1 (V_EMP_ID DBMS_SQL.NUMBER_TABLE)
IS
     lv_error_string VARCHAR2(4000);
BEGIN
    FORALL INDX IN V_EMP_ID.FIRST..V_EMP_ID.LAST SAVE EXCEPTIONS
    UPDATE EMPLOYEES 
     ---trying to rasie an exception by using a calculation
    SET SALARY=SALARY * 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
    WHERE ID_E= V_EMP_ID(INDX);

EXCEPTION
    WHEN OTHERS 
    THEN
    FOR i IN 1 .. SQL%BULK_EXCEPTIONS.COUNT
    LOOP
        ---Am printing the value of the exception array.
        dbms_output.put_line('exception Raised for record' ||V_EMP_ID(i));           

    END LOOP;
END;
/

输出:

SQL> DECLARE
     empid   DBMS_SQL.NUMBER_TABLE;
    BEGIN
     empid (1) := 1;
     empid (2) := 9;

     PROC1 (empid);
   END;  

/
exception Raised for record  1

PL/SQL procedure successfully completed.

【讨论】:

  • 我对 SQL%BULK_EXCEPTIONS 及其包含的行的理解是它们只是例外情况,因此与您所在的表 (V_EMP_ID) 中的行不会存在一对一的关系在 FORALL 中迭代。不是这样吗?基本上索引 i 很可能不等于索引 INDX
  • SQL%BULK_EXCEPTIONS 是一个隐式游标,它包含所有引发的异常。在异常块中,我们只是打印它。所以 FORALL 循环单独运行,异常单独阻塞隐式游标循环。这就是示例中显示的内容。我正在传递一个数字集合并在异常块中捕获异常。
  • 是的,经过更多研究,我发现确实如此,非常感谢。
猜你喜欢
  • 1970-01-01
  • 2017-11-01
  • 2010-09-09
  • 1970-01-01
  • 1970-01-01
  • 2017-04-20
  • 2018-11-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多