【发布时间】:2014-03-09 19:29:19
【问题描述】:
我正在使用下面的BULK COMMIT proc 将记录从TABLESOURCE 插入到TABLE1。
COLUMN1 上的 TABLE1 定义为 NOT NULL。
有时我的 TABLE_SOURCE 返回零行,在这种情况下,我的 PROC 会因错误而失败:
Ora - 6502 数值或数值错误
我尝试在异常中使用NO_DATA_FOUND 忽略错误,但它也不起作用。
请告诉我如何解决这个问题?
create or replace PROCEDURE PROC1 AS
v_ErrNum NUMBER (20);
v_ErrMsg VARCHAR2 (270);
v_Last_Record PLS_INTEGER;
CURSOR c_Get_Record
IS
SELECT Column1, Column2, Column3
FROM Table1;
TYPE Target_Rec IS TABLE OF Table1%ROWTYPE
INDEX BY PLS_INTEGER;
a_Target_Rec Target_Rec;
TYPE FetchSet IS TABLE OF c_Get_Record%ROWTYPE;
a_Fetch_Set FetchSet;
TYPE cursor_var_type IS REF CURSOR;
CV cursor_var_type;
BEGIN
OPEN CV FOR
Select Column1, Column2, Column3 from TABLE_SOURCE where Column1 is NOT NULL;
FETCH CV
BULK COLLECT INTO a_Fetch_Set;
CLOSE CV;
v_Last_Record := a_Fetch_Set.LAST;
FOR i IN 1 .. v_Last_Record
LOOP
a_Target_Rec (i).Column1 := a_Fetch_Set (i).Column1;
a_Target_Rec (i).Column2 := a_Fetch_Set (i).Column2;
a_Target_Rec (i).Column3 := a_Fetch_Set (i).Column3;
END LOOP;
v_Last_Record := 0;
v_Last_Record := a_Target_Rec.LAST;
FORALL j IN 1 .. v_Last_Record
INSERT INTO TABLE1
VALUES a_Target_Rec (j);
COMMIT;
-- *** ** Error Handling ** ***
EXCEPTION
WHEN OTHERS THEN
v_ErrNum := SQLCODE ;
v_ErrMsg := SUBSTR( SQLERRM, 0, 250) ;
RAISE_APPLICATION_ERROR( -20067 , 'ERROR WHILE LOADING TABLE1 Error Msg: ' || dbms_utility.format_error_stack|| dbms_utility.format_error_backtrace) ;
ROLLBACK ;
END PROC1;
【问题讨论】:
-
好吧,它在哪一行失败???
-
你不能把它改写成简单的 SQL 吗?这更难遵循,更容易出错,而且肯定会更慢。
-
你好大卫,我的实际 PROC 有近 10 多个复杂联合,而不是我上面提供的 Select 子句。为了提高处理速度,我们切换到 BULK COMMIT 模式。正如 Dmitry 建议的那样,我切换到 COUNT 而不是 LAST 并且它起作用了,
-
查询复杂性无关紧要——所有数据都通过 SQL 访问,在其上放置 PL/SQL 逻辑只会减慢速度。无论如何,很高兴它一直在工作。