2017-01-20 6 views
-1

FORALL 업데이트가 컬렉션의 마지막 레코드 만 업데이트 중이므로 오류 ORA-22160 : element가 표시됩니다. 색인 [1]이 (가) 없습니다. 나는 시나리오를 가지고 있는데 나는 백만 건의 레코드를 업데이트해야만했다. 아래 코드를 실행하면 100 번째 레코드에서 99 개의 레코드가 동일하게 유지됩니다 (100 개의 레코드로 테스트 됨). 실행 후 ORA-22160 : index [1]의 요소가 존재하지 않습니다. 나는이 문제에 대한 오라클 9i database.need 제안을 사용하고 있습니다. 당신이 수집 r12_inv_id의 범위에 r12_iflow 컬렉션을 사용하고 있기 때문에FORALL 업데이트가 컬렉션의 마지막 레코드 만 업데이트 중이며 오류가 발생합니다. ORA-22160 : 인덱스 [1]의 요소가 존재하지 않습니다. 오류 메시지

Declare 
CURSOR tk_iflow_cur 
    IS 
    SELECT DISTINCT top.rule_id, 
     top.rule_item_id, 
     msib.segment2 
    FROM iflow_rules top, 
     iflow_active_rules msib 
    WHERE top.rule_id = msib.rule_item_id 
    AND msib.organization_id = 5039 and rownum<=100 
    ORDER BY top.ora_inv_item_id; -- cursor fetches 100 row 
    ---Variable declaration 
TYPE l_iflow_id 
IS 
    TABLE OF VARCHAR2(200) INDEX BY BINARY_INTEGER; 
TYPE l_iflow_org 
IS 
    TABLE OF NUMBER INDEX BY BINARY_INTEGER; 
TYPE l_iflow_inv_id 
IS 
    TABLE OF NUMBER INDEX BY BINARY_INTEGER; 
TYPE l_r12_inv_id 
IS 
    TABLE OF NUMBER; 
TYPE l_r12_item_key 
IS 
    TABLE OF VARCHAR2(200) INDEX BY BINARY_INTEGER; 
TYPE l_r12_iflow 
IS 
    TABLE OF VARCHAR2(200) INDEX BY BINARY_INTEGER; 
TYPE l_omar_item_id 
IS 
    TABLE OF NUMBER INDEX BY BINARY_INTEGER; 
TYPE l_omar_seg2 
IS 
    TABLE OF VARCHAR2(200) INDEX BY BINARY_INTEGER; 
    tk_iflow_id l_iflow_id; 
    tk_iflow_org l_iflow_org; 
    tk_iflow_inv_id l_iflow_inv_id; 
    t_omar_item_id l_omar_item_id; 
    t_omar_seg2 l_omar_seg2; 
    r12_inv_id l_r12_inv_id:=l_r12_inv_id(); 
    r12_item_key l_r12_item_key; 
    r12_iflow l_r12_iflow; 
    user_excep EXCEPTION; 
    v_err_count NUMBER; 
    PRAGMA EXCEPTION_INIT (user_excep, -24381); 
    r12_item_id2 VARCHAR2(200); 


BEGIN -- 
    tk_iflow_id.DELETE; 
    tk_iflow_inv_id.DELETE; 
    OPEN tk_iflow_cur; 
    LOOP --Cursor Loop 
    tk_iflow_id.DELETE; 
    tk_iflow_inv_id.DELETE; 
    t_omar_seg2.DELETE; 
    FETCH tk_iflow_cur BULK COLLECT INTO tk_iflow_id, tk_iflow_inv_id, t_omar_seg2; ---100 records assigned to variables 
    FOR i IN 1..tk_iflow_id.COUNT -- to store the cursor value 
    LOOP       --for Loop 
     BEGIN 
     --Comment : passing the cursor value to derive new records from different instance for updating the records 
     SELECT DISTINCT segment1, 
      inventory_item_id, 
      item_type 
     INTO r12_iflow(i), 
      r12_item_id2, 
      r12_item_key(i) 
     FROM [email protected]_db_link 
     WHERE segment1   =tk_iflow_id(i) 
     AND NVL(SEGMENT2,'NULL') = NVL(t_omar_seg2(i),'NULL') 
     AND organization_id  =5063; 
     EXCEPTION 
     WHEN OTHERS THEN 
     r12_inv_id(i) := 0; 
     r12_item_key(i) := 0; 
     END; 
     r12_inv_id :=l_r12_inv_id(); 
     r12_inv_id.EXTEND (i); 
     r12_inv_id (i) := r12_item_id2; 

    END LOOP; --end for loop 
    BEGIN 
     FORALL i IN r12_inv_id.FIRST..r12_inv_id.LAST SAVE EXCEPTIONS -- for all the derived records i'm updating the target table.100 records i'm updating 
     UPDATE iflow_active_rules 
     SET ora_org_id  =5063, 
     ora_inv_item_id =r12_inv_id(i) 
     WHERE iflow_id  =r12_iflow(i) 
     AND ora_inv_item_id = tk_iflow_inv_id(i); 
    EXCEPTION 
    WHEN user_excep THEN 
     v_err_count := SQL%BULK_EXCEPTIONS.COUNT; 
     FOR i  IN 1 .. v_err_count 
     LOOP 
     DBMS_OUTPUT.put_line ('Error: ' || i || ' Array Index: ' || SQL%BULK_EXCEPTIONS (i).ERROR_INDEX || ' Message: ' || SQLERRM (SQL%BULK_EXCEPTIONS (i).ERROR_CODE)); 
     END LOOP; 
    END; 
    BEGIN 
     FORALL i IN r12_inv_id.FIRST .. r12_inv_id.LAST SAVE EXCEPTIONS 
     UPDATE iflow_rules --- updating openup system iflow cost details 
     SET ora_org_id  =5063, 
     ora_inv_item_id =r12_inv_id(i) 
     WHERE iflow_id  =r12_iflow(i) 
     AND ora_inv_item_id = tk_iflow_inv_id(i) ; 
    EXCEPTION 
    WHEN user_excep THEN 
     v_err_count := SQL%BULK_EXCEPTIONS.COUNT; 
     FOR i  IN 1 .. v_err_count 
     LOOP 
     DBMS_OUTPUT.put_line ('Error: ' || i || ' Array Index: ' || SQL%BULK_EXCEPTIONS (i).ERROR_INDEX || ' Message: ' || SQLERRM (SQL%BULK_EXCEPTIONS (i).ERROR_CODE)); 
     END LOOP; 
    END; 
    EXIT 
    WHEN tk_iflow_id.COUNT=0; 
    COMMIT; 
    END LOOP; --End Cursor Loop 
    CLOSE tk_iflow_cur; 
END; 

답변

0

이런 일이 어디에 액세스 할 수 없습니다 없습니다. FORALL 진술은 FOR LOOP과 다릅니다. 비록 그들은 같은 논리에서 꽤 잘 작동하지만 변수의 사용 범위가 다릅니다. 귀하의 케이스에 RECORD을 생성하고 처리 할 수 ​​있습니다. 어떻게 할 수 있는지 아래에서 확인하십시오. PS 테스트되지 않았습니다.

DECLARE 
    CURSOR tk_iflow_cur 
    IS 
     SELECT DISTINCT top.rule_id, top.rule_item_id, msib.segment2 
      FROM iflow_rules top, iflow_active_rules msib 
     WHERE  top.rule_id = msib.rule_item_id 
       AND msib.organization_id = 5039 
       AND ROWNUM <= 100 
     ORDER BY top.ora_inv_item_id;     -- cursor fetches 100 row 


    Type var_cur is table of tk_iflow_cur%rowtype index by pls_integer;  
    l_cur var_cur; 

    --Record of your variables. 
    TYPE var_rec is RECORD 
    (
     l_r12_iflow VARCHAR2 (200), 
     l_r12_inv_id number, 
     l_r12_item_key VARCHAR2 (200) 

    ); 

    TYPE rec is table of var_rec index by pls_integer; 

    --Variable declared to hold the result of your cursor. 
    l_rec rec; 

    user_excep  EXCEPTION; 
    v_err_count  NUMBER; 
    PRAGMA EXCEPTION_INIT (user_excep, -24381); 
    r12_item_id2  VARCHAR2 (200); 
BEGIN                   
    OPEN tk_iflow_cur; 

    LOOP               --Cursor Loop  

     FETCH tk_iflow_cur BULK COLLECT INTO l_cur LIMIT 100; ---100 records assigned to variables   

     FOR i IN 1 .. l_cur.COUNT    -- to store the cursor value 
     LOOP               --for Loop 
     BEGIN 
      --Comment : passing the cursor value to derive new records from different instance for updating the records 
      SELECT DISTINCT segment1, inventory_item_id, item_type 
       INTO l_rec(i).l_r12_iflow ,l_rec(i).l_r12_inv_id ,l_rec(i).l_r12_item_key 
       FROM [email protected]_db_link 
      WHERE segment1 = l_cur(i).rule_id 
       AND NVL (SEGMENT2, 'NULL') = NVL (l_cur(i).segment2 , 'NULL') 
       AND organization_id = 5063; 
     EXCEPTION 
      WHEN OTHERS 
      THEN 
       l_rec(i).l_r12_iflow := 0; 
       l_rec(i).l_r12_inv_id:= 0; 
       l_rec(i).l_r12_item_key := ''; 
     END; 

     END LOOP;             --end for loop 

     BEGIN 
     FORALL i IN 1 .. l_rec.COUNT SAVE EXCEPTIONS -- for all the derived records i'm updating the target table.100 records i'm updating 
      UPDATE iflow_active_rules 
       SET ora_org_id = 5063, 
        ora_inv_item_id = l_rec(i).l_r12_inv_id 
      WHERE  iflow_id = l_rec(i).l_r12_iflow 
       AND ora_inv_item_id = l_rec(i).l_r12_inv_id; 

     EXCEPTION 
     WHEN user_excep 
     THEN 
      v_err_count := SQL%BULK_EXCEPTIONS.COUNT; 

      FOR i IN 1 .. v_err_count 
      LOOP 
       DBMS_OUTPUT.put_line (
        'Error: ' 
        || i 
        || ' Array Index: ' 
        || SQL%BULK_EXCEPTIONS (i).ERROR_INDEX 
        || ' Message: ' 
        || SQLERRM (SQL%BULK_EXCEPTIONS (i).ERROR_CODE)); 
      END LOOP; 
     END; 

     BEGIN 
     FORALL i IN 1..l_rec.COUNT SAVE EXCEPTIONS 
      UPDATE iflow_rules --- updating openup system iflow cost details 
       SET ora_org_id = 5063, 
        ora_inv_item_id = l_rec(i).l_r12_inv_id 
      WHERE  iflow_id = l_rec(i).l_r12_iflow 
      AND ora_inv_item_id = l_rec(i).l_r12_inv_id; 

     EXCEPTION 
     WHEN user_excep 
     THEN 
      v_err_count := SQL%BULK_EXCEPTIONS.COUNT; 

      FOR i IN 1 .. v_err_count 
      LOOP 
       DBMS_OUTPUT.put_line (
        'Error: ' 
        || i 
        || ' Array Index: ' 
        || SQL%BULK_EXCEPTIONS (i).ERROR_INDEX 
        || ' Message: ' 
        || SQLERRM (SQL%BULK_EXCEPTIONS (i).ERROR_CODE)); 
      END LOOP; 
     END; 

     EXIT WHEN tk_iflow_cur%NOTFOUND; 
    END LOOP;             --End Cursor Loop 

    COMMIT; 
    CLOSE tk_iflow_cur; 

END;