2017-01-25 19 views
1

Java配列をストアドプロシージャに渡して、配列の値でレコードを更新しようとしています。私はJava配列をストアドプロシージャに渡す

Error:ORA-06531: Reference to uninitialized collection.

に実行していますストアドプロシージャを実行し、テストしようとすると、現在誰が正しい方向に私を押すか、私は私のコードをクリーンアップに役立つことができます。以下は、本体のパッケージ仕様です。

CREATE OR REPLACE package AOMS.test_array1 as 

type t1 is record (
s1 varchar2(1), 
i_part_no varchar2(20), 
i_itc varchar2(20), 
s2 varchar2(1), 
l_part_no varchar2(20)); 

type tab1 is table of t1 ; 

tab2 tab1; 

ここはボディです。

CREATE OR REPLACE PACKAGE BODY AOMS.TEST_ARRAY1 AS 

I_ARRAY varchar2(1000); 

PROCEDURE test_array2(i_array IN tab2%TYPE) AS 

    l_s1 VARCHAR2(50); 
    l_part_no1 VARCHAR2(50); 
    l_itc varchar2(50); 
    l_s2 varchar2(50); 
    l_part_no2 varchar2(50); 

BEGIN 
    FOR x IN i_array.first .. i_array.last 
    LOOP 
    l_s1 := i_array(x).s1; 
    l_part_no1 := i_array(x).i_part_no; 
    l_itc := i_array(x).i_itc; 
    l_s2 := i_array(x).s2; 
    l_part_no2 := i_array(x).l_part_no; 

    UPDATE replacement_parts 
    SET frst_src = l_s1, 
    frst_part_no = l_part_no1, 
    ITC = l_itc, 
    last_src = l_s2, 
    last_part_no = l_part_no2 


    WHERE  
    frst_src = 'P' 
    AND frst_part_no = '96424447   '; 
COMMIT; 
END LOOP; 
END test_array2; 
END test_array1; 
/

私はToadを使用しているので、手順を呼び出すと右クリックして実行し、自分のパラメータを入力します。ここでは、実行しようとすると生成される無名ブロックコードを示します。

DECLARE 
    I_ARRAY AOMS.TEST_ARRAY1.tab2%type; 

BEGIN 
    -- I_ARRAY := NULL; Modify the code to initialize this parameter 

    AOMS.TEST_ARRAY1.TEST_ARRAY2 (I_ARRAY); 
    COMMIT; 
END; 
+0

問題は発信者にあるようです。プロシージャの呼び出しに使用するコードを投稿してください。 – Aleksej

+0

私の投稿を更新しました。 – Jules

答えて

1

パッケージとプロシージャコールの両方に問題があります。 これは動作するはずです:

CREATE OR REPLACE PACKAGE test_array1 AS 
    TYPE t1 IS RECORD 
    (
     s1          VARCHAR2(1), 
     i_part_no        VARCHAR2(20), 
     i_itc         VARCHAR2(20), 
     s2          VARCHAR2(1), 
     l_part_no        VARCHAR2(20) 
    ); 

    TYPE tab1 IS TABLE OF t1; 

    tab2         tab1; 

    PROCEDURE test_array2(i_array IN tab1); 
END test_array1; 
CREATE OR REPLACE PACKAGE BODY TEST_ARRAY1 AS 
    I_ARRAY         VARCHAR2(1000); 

    PROCEDURE test_array2(i_array IN tab1) IS 
     l_s1         VARCHAR2(50); 
     l_part_no1        VARCHAR2(50); 
     l_itc         VARCHAR2(50); 
     l_s2         VARCHAR2(50); 
     l_part_no2        VARCHAR2(50); 
    BEGIN 
     IF i_array.COUNT > 0 
     THEN 
      FOR x IN i_array.FIRST .. i_array.LAST 
      LOOP 
       l_s1   := i_array(x).s1; 
       l_part_no1 := i_array(x).i_part_no; 
       l_itc   := i_array(x).i_itc; 
       l_s2   := i_array(x).s2; 
       l_part_no2 := i_array(x).l_part_no; 

       UPDATE replacement_parts 
        SET frst_src  = l_s1, 
         frst_part_no = l_part_no1, 
         ITC    = l_itc, 
         last_src  = l_s2, 
         last_part_no = l_part_no2 
       WHERE  frst_src = 'P' 
         AND frst_part_no = '96424447   '; 

       COMMIT; 
      END LOOP; 
     END IF; 
    END test_array2; 
END test_array1; 
/

コール:

DECLARE 
    I_ARRAY TEST_ARRAY1.tab1; 

BEGIN 
    I_ARRAY := TEST_ARRAY1.tab1(); 

    TEST_ARRAY1.TEST_ARRAY2 (I_ARRAY); 
    COMMIT; 
END; 

私が行った変更:

  • プロシージャを宣言するvariable%typeのようなものを使用し、その後、あなたのパッケージで型を定義しますあなたは単純にそのタイプを使うことができます。
  • をパッケージに入れてコレクションをスキャンするときは、コレクションに値があるかどうかを確認してから、collection.firstを使用してください。空のコレクションの.firstにアクセスしようとすると、問題が発生する可能性があります。呼び出し側で
  • は、あなたは、あなたがより良い変数、型、手続きのためのより多くの説明名前を使用するようにしてください、私はあなたがわきとして

を持っているエラーを回避するために示した方法は、コレクションを初期化する必要があります異なるオブジェクト間の混乱を避けるためにパッケージを作成します。

別のこと:ループ内にcommitがあります。つまり、3つのレコードが更新されてエラーが発生した場合は、3つの更新をコミットします。これは本当に必要なものですか?また、この方法では、呼び出し元のcommitは役に立たない。

+0

ありがとうございましたこれは非常に役に立ちました。私のコードは正常にコンパイルできました。今、私は配列がどのように渡されるのか把握しなければなりません。:p – Jules

関連する問題