2014-02-11 4 views
0

Я использую ниже BULK COMMIT proc для вставки записей с TABLESOURCE в TABLE1. COLUMN1 по адресу TABLE1 определяется как NOT NULL.Ora-6502 Числовая или значение ошибки, Вставьте пустое значение в таблицу, которая имеет NOT NULL столбец

Иногда мои TABLE_SOURCE возвращает ноль строк, и в этом случае моего PROC терпит неудачу с ошибкой:

Ora - 6502 Numeric or value error

Я пытался игнорировать эту ошибку, используя 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; 
+0

Ну, в какой строке это не удается ??? – OldProgrammer

+0

Можете ли вы не просто переписать это как простой SQL? Это намного сложнее, чем больше подвержено ошибкам, и гарантированно будет медленнее. –

+0

Привет, Дэвид, мой фактический PROC имеет почти 10+ Сложных Unions вместо этого предложения Select, которое я изложил выше. Чтобы улучшить скорость процесса, мы переключились на режим BULK COMMIT. as Dmitry Предлагаемый я переключился на COUNT вместо LAST, и он сработал, – Ragav

ответ

1

Вы получаете проблему из-за

v_Last_Record := a_Fetch_Set.LAST; 

    FOR i IN 1 .. v_Last_Record 

В случае, если ваш курсор не имеет строк набухают собирать не заполняет коллекцию и a_Fetch_Set пуст. В этом случае LAST возвращает NULL. Вы должны проверить это или использовать a_Fetch_Set.COUNT.