【Oracle】PLS-00905の原因と解決方法|object is invalid・オブジェクトが無効です

【Oracle】PLS-00905の原因と解決方法|object is invalid・オブジェクトが無効です Oracle

PLS-00905: object string is invalid は、PL/SQLから参照しているパッケージ、プロシージャ、ファンクション、トリガー、型などのオブジェクトが INVALID 状態の時に発生するエラーです。

多くの場合、PLS-00905そのものが根本原因ではありません。参照先オブジェクトの中にコンパイルエラーがあり、その結果として「このオブジェクトは無効なので使えない」と表示されています。まず USER_ERRORSSHOW ERRORS で、無効になっている本当の理由を確認します。

先に結論
PLS-00905が出たら、エラーメッセージに出ているオブジェクト名を確認し、USER_OBJECTS / ALL_OBJECTSSTATUS を見ます。INVALIDなら USER_ERRORS / ALL_ERRORS でコンパイルエラー本文を読み、ALTER PACKAGE ... COMPILE BODY などで再コンパイルします。ORA-06508やORA-04063と一緒に出る場合も、直すべき対象は無効な呼び出し先です。
スポンサーリンク

PLS-00905とは

Oracle公式の説明では、PLS-00905は、参照しているパッケージ仕様部またはストアドサブプログラムが無効な時に発生します。対処としては、何がそのオブジェクトを無効にしたのかを調べ、エラーなく再コンパイルできる状態にする必要があります。

実務では、パッケージの本体が壊れている、仕様部と本体が一致していない、参照先テーブルや列が変わった、権限不足でコンパイルできない、依存オブジェクトが無効、というケースでよく見ます。

表示例 よくある意味 最初に見る場所
PLS-00905: object APP.PKG_ORDER is invalid パッケージまたは本体がINVALID USER_OBJECTS / USER_ERRORS
PLS-00905: object APP.P_SYNC is invalid プロシージャがINVALID SHOW ERRORS PROCEDURE
PLS-00905 + ORA-06508 呼び出し先が実行時に使えない ALL_OBJECTS / ALL_ERRORS
PLS-00905 + ORA-04063 対象オブジェクトにコンパイルエラーが残っている USER_ERRORS

直近の関連エラーとして、呼び出し先が使えない時は ORA-06508の原因と解決方法、オブジェクトにエラーがある時は ORA-04063の原因と解決方法 も一緒に確認すると切り分けやすくなります。

まず確認する順番

PLS-00905は、エラー名だけを見ても原因が抽象的です。次の順番で、対象、状態、コンパイルエラー、依存関係を確認します。

順番 確認すること 使うもの
1 エラーメッセージに出ているオブジェクト名 PLS-00905: object ... is invalid
2 対象のオブジェクト種別と状態 USER_OBJECTS / ALL_OBJECTS
3 コンパイルエラー本文 USER_ERRORS / ALL_ERRORS
4 パッケージ仕様部と本体の状態 PACKAGE / PACKAGE BODY
5 参照先オブジェクトの状態 USER_DEPENDENCIES
6 権限不足やシノニムの解決先 ALL_TAB_PRIVS / ALL_SYNONYMS
7 修正後の再コンパイル ALTER ... COMPILE

対象オブジェクトがINVALIDか確認する

まず、PLS-00905に出ているオブジェクトが本当に INVALID かを確認します。パッケージの場合は、仕様部と本体が別行で出る点に注意してください。

check-invalid-object.sql
SELECT object_name,
       object_type,
       status,
       last_ddl_time
FROM user_objects
WHERE object_name IN ('PKG_ORDER', 'P_SYNC', 'F_CALC_TAX')
ORDER BY object_name, object_type;

PACKAGE がVALIDでも、PACKAGE BODY がINVALIDならPLS-00905やORA-06508の原因になります。仕様部だけ見て安心せず、本体の状態も確認します。

USER_ERRORSでコンパイルエラーを見る

対象がINVALIDなら、次に USER_ERRORS を見ます。ここに出ている PLS-ORA- の先頭エラーが、実際に直すべき原因です。

user-errors.sql
SELECT name,
       type,
       sequence,
       line,
       position,
       text
FROM user_errors
WHERE name = 'PKG_ORDER'
ORDER BY type, sequence;

SQL*PlusやSQLclで作業している場合は、SHOW ERRORS でも確認できます。引数なしでは直前のコンパイル対象に依存するため、調査時はオブジェクト種別と名前を明示するのが安全です。

show-errors.sql
SHOW ERRORS PACKAGE pkg_order;
SHOW ERRORS PACKAGE BODY pkg_order;
SHOW ERRORS PROCEDURE p_sync;
SHOW ERRORS FUNCTION f_calc_tax;
SHOW ERRORS TRIGGER trg_orders_bi;

コンパイルエラー全般の読み方は PL/SQLコンパイル時エラーとUSER_ERRORSの使い方 でも詳しく解説しています。

PACKAGEとPACKAGE BODYの違いに注意する

PLS-00905では、パッケージ仕様部とパッケージ本体の違いを取り違えると調査が長引きます。仕様部は外部公開インターフェース、本体は実装です。呼び出し側は仕様部を見ますが、実行時には本体も必要です。

対象 役割 INVALID時の影響
PACKAGE 仕様部。公開するプロシージャ・関数・型などを定義 呼び出し元も広く無効化されやすい
PACKAGE BODY 本体。仕様部で宣言した処理の実装 呼び出し時にPLS-00905/ORA-06508になりやすい
仕様部変更 引数や戻り値などの契約変更 依存オブジェクトの再コンパイルが必要
本体変更 実装だけの変更 通常は仕様部依存の呼び出し元を無効化しにくい
package-compile.sql
-- 仕様部を再コンパイル
ALTER PACKAGE pkg_order COMPILE;

-- 本体を再コンパイル
ALTER PACKAGE pkg_order COMPILE BODY;

-- エラー確認
SELECT type, line, position, text
FROM user_errors
WHERE name = 'PKG_ORDER'
ORDER BY type, sequence;

CREATE OR REPLACEが成功したように見えるケース

CREATE OR REPLACE PACKAGE BODYCREATE OR REPLACE PROCEDURE を実行した時、オブジェクト自体は作成されても、コンパイルエラーを持ったINVALID状態で残ることがあります。DDLが通ったように見えても、実行時にPLS-00905やORA-06508で落ちるのはこのパターンです。

create-or-replace-check.sql
CREATE OR REPLACE PACKAGE BODY pkg_order AS
  PROCEDURE sync_order IS
  BEGIN
    -- ここに存在しない列や権限不足の参照があるとINVALIDで残る
    NULL;
  END;
END pkg_order;
/

-- 作成直後に必ず確認する
SHOW ERRORS PACKAGE BODY pkg_order;

SELECT object_name, object_type, status
FROM user_objects
WHERE object_name = 'PKG_ORDER'
ORDER BY object_type;

リリース手順では、DDL実行の成否だけでなく、直後の SHOW ERRORSUSER_ERRORSUSER_OBJECTS.STATUS まで確認するのが安全です。

よくある原因と対処

原因 出やすい下位エラー 対処
参照先テーブルや列が変わった ORA-00904 / ORA-00942 SQLや列名を現行定義に合わせる
仕様部と本体が一致していない PLS-00323 / PLS-00306 引数・戻り値・公開手続きの宣言を合わせる
必要な権限が直接付与されていない PLS-00201 / ORA-00942 ロールではなく直接GRANTする
依存先オブジェクトがINVALID PLS-00905 の連鎖 依存先から順に再コンパイルする
シノニムが古い実体を指している ORA-04043 / PLS-00201 シノニム解決先と実体を確認する
パッケージ差し替え後の既存セッション ORA-06508 / ORA-04068 接続プール再接続やリトライ設計を確認する

ORA-06550と一緒に出る場合

PLS-00905は、匿名ブロックや呼び出しSQLの中で ORA-06550 と一緒に表示されることがあります。この場合、ORA-06550は「PL/SQLブロックのコンパイルまたは実行に失敗した」という入口で、実際に見るべきなのは後続のPLS-00905です。

ora-06550-pls-00905-example.sql
BEGIN
  pkg_order.sync_order;
END;
/

-- 例:
-- ORA-06550: line 2, column 3:
-- PLS-00905: object APP.PKG_ORDER is invalid
-- ORA-06550: line 2, column 3:
-- PL/SQL: Statement ignored

-- 対応: 呼び出し元ではなくPKG_ORDER側のエラーを確認する
SELECT type, line, position, text
FROM user_errors
WHERE name = 'PKG_ORDER'
ORDER BY type, sequence;

PL/SQL: Statement ignored は、PLS-00905の結果としてその呼び出し文が無視された、という意味です。呼び出し文の構文だけを直すのではなく、無効になっている対象オブジェクトを直します。

依存関係を確認する

対象オブジェクトだけを再コンパイルしても直らない場合は、参照先が壊れていることがあります。依存先から順にVALIDへ戻すと、PLS-00905の連鎖を追いやすくなります。

dependencies.sql
SELECT name,
       type,
       referenced_owner,
       referenced_name,
       referenced_type
FROM user_dependencies
WHERE name = 'PKG_ORDER'
ORDER BY referenced_owner, referenced_type, referenced_name;

SELECT object_name, object_type, status
FROM user_objects
WHERE status <> 'VALID'
ORDER BY object_type, object_name;

権限不足でINVALIDになるケース

PL/SQLオブジェクト内で別スキーマの表やパッケージを参照する場合、ロール経由の権限だけではコンパイルできないことがあります。作業ユーザーでSELECTできるのにパッケージがINVALIDになる場合は、直接付与権限を確認します。

direct-grant.sql
-- 参照先所有者から、PL/SQLオブジェクト所有者へ直接付与する
GRANT SELECT ON master_schema.customers TO app_schema;
GRANT EXECUTE ON master_schema.util_pkg TO app_schema;

-- 付与後に再コンパイル
ALTER PACKAGE app_schema.pkg_order COMPILE BODY;

権限不足の切り分けは ORA-01031 insufficient privilegesの原因と対処 も参考になります。

シノニムや別スキーマを確認する

エラーに出ている名前と、実際に参照している実体が違うこともあります。特にパブリックシノニムや別スキーマの同名パッケージがある環境では、どの実体に解決されているかを確認します。

synonym-check.sql
SELECT owner,
       synonym_name,
       table_owner,
       table_name,
       db_link
FROM all_synonyms
WHERE synonym_name IN ('PKG_ORDER', 'P_SYNC')
ORDER BY owner, synonym_name;

SELECT owner, object_name, object_type, status
FROM all_objects
WHERE object_name IN ('PKG_ORDER', 'P_SYNC')
ORDER BY owner, object_type, object_name;

再コンパイルの基本コマンド

原因を直したら、対象オブジェクトを明示して再コンパイルします。OracleのCOMPILE句は、VALID/INVALIDに関係なくPL/SQLユニットを再コンパイルできます。

compile-commands.sql
ALTER PACKAGE pkg_order COMPILE;
ALTER PACKAGE pkg_order COMPILE BODY;
ALTER PROCEDURE p_sync COMPILE;
ALTER FUNCTION f_calc_tax COMPILE;
ALTER TRIGGER trg_orders_bi COMPILE;

SELECT object_name, object_type, status
FROM user_objects
WHERE object_name IN ('PKG_ORDER', 'P_SYNC', 'F_CALC_TAX')
ORDER BY object_type, object_name;

本番障害時の調査SQLセット

本番で急いで切り分ける場合は、対象オブジェクト名を1つ決めて、状態、エラー、依存関係をまとめて確認します。

pls-00905-investigation.sql
DEFINE obj_name = 'PKG_ORDER'

SELECT owner, object_name, object_type, status, last_ddl_time
FROM all_objects
WHERE object_name = UPPER('&obj_name')
ORDER BY owner, object_type;

SELECT owner, name, type, line, position, text
FROM all_errors
WHERE name = UPPER('&obj_name')
ORDER BY owner, type, sequence;

SELECT name, type, referenced_owner, referenced_name, referenced_type
FROM user_dependencies
WHERE name = UPPER('&obj_name')
ORDER BY referenced_owner, referenced_type, referenced_name;

ALL_ERRORS にエラーが出ている場合は、その先頭から直します。エラーが出ないのにPLS-00905が続く場合は、実行ユーザー、シノニム解決、別スキーマの同名オブジェクトを確認してください。

リリース後にPLS-00905を残さない確認

PLS-00905は、リリース直後の疎通確認で見つかることが多いエラーです。本番反映後は、INVALIDオブジェクトとコンパイルエラーが残っていないかを確認します。

post-release-check.sql
SELECT object_name, object_type, status
FROM user_objects
WHERE status <> 'VALID'
ORDER BY object_type, object_name;

SELECT name, type, line, position, text
FROM user_errors
ORDER BY name, type, sequence;

PLS-00905と関連エラーの違い

エラー 意味 見るべき場所
PLS-00905 参照しているオブジェクトが無効 USER_OBJECTS / USER_ERRORS
ORA-06508 呼び出し先PL/SQLユニットを実行時に利用できない ALL_OBJECTS / ALL_ERRORS
ORA-06550 PL/SQLブロック全体の失敗を示す入口 後続の PLS- エラー
ORA-04063 オブジェクトにコンパイルエラーがある USER_ERRORS
ORA-04098 トリガーが無効で再検証に失敗 SHOW ERRORS TRIGGER
ORA-04068 パッケージ状態が破棄された 既存セッションとパッケージ状態
PLS-00201 識別子が宣言されていない 名前ミス、権限、スコープ

トリガー内から無効なパッケージを呼んでいる場合は、ORA-04098の原因と解決方法 も確認してください。パッケージ状態が絡む場合は ORA-04068の解説 も参考になります。

修正チェックリスト

項目 確認内容 OKの状態
対象 PLS-00905に出ているオブジェクト名を特定したか スキーマ名・種別まで把握
状態 USER_OBJECTS.STATUS を確認したか 対象がVALID
本体 PACKAGE BODYも確認したか 仕様部と本体がVALID
エラー USER_ERRORS の先頭エラーを読んだか エラー0件
依存先 参照先がVALIDか 依存先もVALID
権限 直接権限があるか 必要なSELECT/EXECUTEが直接付与済み
再確認 再コンパイル後に実行テストしたか PLS-00905が再現しない

よくある質問

PLS-00905は再コンパイルだけで直りますか?

参照先が一時的に無効だっただけなら直ることがあります。ただし USER_ERRORS にエラーが残っている場合は、定義や権限を直さない限りINVALIDのままです。

PACKAGEはVALIDなのにPLS-00905になります

PACKAGE BODY がINVALIDの可能性があります。仕様部だけでなく本体の STATUSUSER_ERRORS を確認してください。

ORA-06508も一緒に出ています

呼び出し先が無効で、実行時に利用できない状態です。ORA-06508だけでなく、PLS-00905に出ている対象オブジェクトを直します。

USER_ERRORSが空なのにPLS-00905になります

調査ユーザーと実行ユーザーが違う、別スキーマの同名オブジェクトを見ている、シノニム経由で別実体を参照している可能性があります。ALL_OBJECTSALL_ERRORSALL_SYNONYMS を確認してください。

本番で一時回避できますか?

呼び出し元処理を止める、直近リリースを切り戻す、問題オブジェクトを修正して再コンパイルする方法があります。根本対応は、INVALIDになった原因を消してVALIDに戻すことです。

まとめ

PLS-00905は、PL/SQLで参照しているオブジェクトが無効な時に発生します。エラー名だけでは原因が抽象的なので、対象オブジェクトの STATUS を確認し、USER_ERRORSSHOW ERRORS で実際のコンパイルエラーを読みます。

よくある原因は、パッケージ本体のINVALID、仕様部と本体の不一致、参照先テーブルや列の変更、権限不足、依存オブジェクトの無効化です。修正後は ALTER PACKAGE ... COMPILE BODY などで明示的に再コンパイルし、INVALIDとエラーが残っていないことを確認してください。

参考

PLS-00905 – Oracle Database Error Help

COMPILE Clause – Oracle Database PL/SQL Language Reference

ALL_ERRORS – Oracle Database Reference