2017-06-16 27 views
1

おそらく不自然なエラーですが、見つからない場合があります。手順で 私はこれを持っている:PLSQLエラー:コンポーネントを宣言する必要があります

PROCEDURE myProcedure(returnCode OUT NUMBER) IS 
CURSOR myCursor IS 
    SELECT column1, column2, column3, column4 FROM MyTable WHERE columX IS NULL AND columnY = 'PS'; 

TYPE myType IS RECORD (
    name1 MyTable.Column1%TYPE, 
    name2 MyTable.Column2%TYPE, 
    name3 MyTable.Column3%TYPE, 
    name4 MyTable.Column4%TYPE 
); 


myVar myType; 
myVar2 typeA 

BEGIN 
    FOR myVar IN myCursor 
    LOOP 
     myVar2 := myVar.name2; 
    END LOOP; 
END; 

ERROR:

PLS-00302 component name2 must be declared 

何が悪いのでしょうか?

のTy

+0

あなたはそれを達成しようとしていると言うことができる場合は、おそらく必要なコードを考え出すことができます。それはあなたがそれを完了するためにかなり欠けているように見えます。 – BriteSponge

答えて

1

myVarカーソルループ変数は、あなたのmyVar、レコード型の変数には関係ありません。そのスコープは型定義を効果的にオーバーライドします。そのタイプを削除した場合も同じエラーが発生します。

From the documentation for cursor for loop

カーソルFOR LOOP文は、暗黙的に、その指定されたカーソルに戻り行タイプのレコード変数としてのループインデックスを宣言する。

a related sectionから:

カーソルFOR LOOP文は暗黙的にそのカーソルが返すタイプの%ROWTYPEレコード変数としてのループ索引を宣言します。このレコードはループに対してローカルであり、ループ実行中にのみ存在します。この構文で

myVarは暗黙カーソル自体と同じ行型であり、column2フィールドではなくname2フィールドを有します。

BEGIN 
    FOR myVar IN myCursor 
    LOOP 
     myVar2 := myVar.column2; 
    END LOOP; 
END; 

およびmyVar変数宣言とmyType型宣言の両方が冗長である:これは動作します。

代わりにあなたがより明示的なカーソル処理を必要とする、あなたのレコードタイプを使用するには:今

BEGIN 
    OPEN myCursor; 
    LOOP 
     FETCH myCursor INTO myVar; 
     EXIT WHEN myCursor%NOTFOUND; 
     myVar2 := myVar.name2; 
    END LOOP; 
    CLOSE myCursor; 
END; 

myVarはまだあなたのmyTypeレコード型変数である - 何がそれをオーバーライドしていない - それはあなたが指定したフィールド名を持っています。

myCursor%rowTypeと明示的に定義して、独自のレコードタイプを必要としないようにすることもできますが、最初のループを作成する方法が長くて、myVar.column2を参照する必要があります。

関連する問題