[Oracle] 9iから10gに移行したプロシージャでコンパイル・エラーが発生 | Archive Redo Blog

Archive Redo Blog

DBエンジニアのあれこれ備忘録

Oracle9iで運用していたデータベースのオブジェクトをエクスポートし、Oracle10gにインポートすると、インポート時にはエラーは出なかったものの、あとで確認するといくつかのプロシージャでコンパイル・エラーが発生していました。

エラーの内容は以下のとおり。

PLS-00371: 宣言セクションでは、' string' の宣言は1 回である必要があります


原因は、該当する変数(パッケージ変数)をパッケージ内で重複して宣言していたため。


なぜかパッケージではエラーとならず、その変数を使用しているプロシージャの方でエラーとなりました。


Oracle9iの場合はこれがエラーにならず、普通にこのような変数を使用することができます。



しかし、実際にパッケージ変数が重複宣言された場合、どれが使用されるのでしょうか? 


簡単にテストしてみました。

まず、以下のようにパッケージ内に'VALID'、'INVALID'、'UNKNOWN'という定数を同じ変数名で宣言し、

CREATE OR REPLACE PACKAGE TEST
IS
    C_TEST VARCHAR2(10) DEFAULT 'VALID';
    C_TEST VARCHAR2(10) DEFAULT 'INVALID';
    C_TEST VARCHAR2(10) DEFAULT 'UNKNOWN';
END;
/

以下のようにこの定数を表示してみました。

BEGIN
    DBMS_OUTPUT.PUT_LINE(TEST.C_TEST);
END;
/


すると、'UNKNOWN'が返ってきます。


どうやら、一番最後に宣言したものが使用されるようです。


というよりも、定義が上書きされると言ったほうが正しそうです。

しかし、何にせよOracle9iでパッケージ変数を重複宣言すると、気づかないうちに意図しない変数を使用することになってしまうので注意が必要です。