【Oracle】ORA-06508の原因と解決方法|PL/SQL: could not find program unit being called

【Oracle】ORA-06508の原因と解決方法|PL/SQL: could not find program unit being called Oracle

ORA-06508: PL/SQL: could not find program unit being called は、PL/SQLから呼び出そうとしたパッケージ、プロシージャ、ファンクションなどのプログラムユニットを、Oracleが実行時に利用できなかった時に発生するエラーです。

名前が本当に存在しない場合だけでなく、呼び出し先が INVALID、パッケージ本体がコンパイルエラー、仕様部と本体の互換性が崩れた、参照先の権限が不足している、既存セッションが古い状態を見ている、という場面でも発生します。

先に結論
ORA-06508が出たら、まずエラーメッセージに出ている呼び出し先オブジェクトを確認します。次に ALL_OBJECTS / USER_OBJECTS で存在と STATUS を見て、USER_ERRORS / ALL_ERRORS でコンパイルエラーを確認します。修正後は ALTER PACKAGE ... COMPILE BODY などで再コンパイルし、アプリケーション側は必要に応じて接続を張り直します。
スポンサーリンク

ORA-06508とは

Oracle公式の説明では、ORA-06508は「呼び出そうとしたストアドプログラムが見つからない」時のエラーです。そのプログラムが削除された、互換性のない形で変更された、またはコンパイルエラーを持っている可能性があります。

つまり、ORA-06508は呼び出し元の行で表示されますが、原因は呼び出し先オブジェクト側にあることが多いです。直近でパッケージ、プロシージャ、ファンクション、トリガー、型を変更した後に出たなら、まずその変更対象を疑います。

よくある表示 意味 最初に見る場所
ORA-06508: PL/SQL: could not find program unit being called: "APP.PKG_ORDER" パッケージが呼べない ALL_OBJECTS / ALL_ERRORS
ORA-04063: package body ... has errors と一緒に出る パッケージ本体にコンパイルエラーがある USER_ERRORS
PLS-00905: object ... is invalid と一緒に出る 呼び出し先がINVALID USER_OBJECTS.STATUS
アプリだけで出る 接続ユーザー、権限、古いセッションの可能性 実行ユーザーで再現確認

直前の記事で扱った ORA-04063 は「オブジェクトにエラーがある」ことを示すエラーです。ORA-06508は、その壊れたオブジェクトを呼び出した側で見える実行時エラーとして出ることがあります。

まず確認する順番

ORA-06508は、再コンパイルだけを繰り返しても原因が見えにくいことがあります。本番障害では、呼び出し先の特定、存在確認、INVALID確認、エラー本文確認、依存関係確認の順で進めると早いです。

順番 確認すること 使うもの
1 エラーメッセージ内のオブジェクト名 ORA-06508 ... "SCHEMA.OBJECT"
2 呼び出し先が存在するか ALL_OBJECTS
3 呼び出し先がVALIDか USER_OBJECTS.STATUS
4 コンパイルエラーがあるか USER_ERRORS / ALL_ERRORS
5 参照先が壊れていないか USER_DEPENDENCIES
6 実行ユーザーに直接権限があるか ALL_TAB_PRIVS など
7 既存セッションが古い状態を持っていないか アプリ接続の張り直し

呼び出し先の存在と状態を確認する

最初に、呼び出し先のオブジェクトが存在するか、種別は何か、状態がVALIDかを確認します。自スキーマだけなら USER_OBJECTS、別スキーマも含めるなら ALL_OBJECTS を使います。

check-called-unit.sql
SELECT owner,
       object_name,
       object_type,
       status,
       last_ddl_time
FROM all_objects
WHERE object_name IN ('PKG_ORDER', 'P_SYNC', 'F_CALC_TAX')
  AND object_type IN ('PACKAGE', 'PACKAGE BODY', 'PROCEDURE', 'FUNCTION')
ORDER BY owner, object_name, object_type;

パッケージの場合は、PACKAGEPACKAGE BODY の両方を見ます。仕様部がVALIDでも、本体がINVALIDなら呼び出し時にORA-06508やORA-04063につながります。

USER_ERRORS / ALL_ERRORSで実原因を見る

呼び出し先がINVALIDなら、次はコンパイルエラーの本文を確認します。ORA-06508は入口であり、実際に直すべきなのは PLS-ORA- の下位エラーです。

called-unit-errors.sql
-- 自スキーマのエラー
SELECT name,
       type,
       sequence,
       line,
       position,
       text
FROM user_errors
WHERE name = 'PKG_ORDER'
ORDER BY type, sequence;

-- 別スキーマを含めて参照可能なエラー
SELECT owner, name, type, line, position, text
FROM all_errors
WHERE name = 'PKG_ORDER'
ORDER BY owner, type, sequence;

SHOW ERRORSUSER_ERRORS の使い分けは PL/SQLコンパイル時エラーの対処ガイド で詳しく整理しています。対話作業なら SHOW ERRORS、自動化や調査SQLなら USER_ERRORS が扱いやすいです。

パッケージ本体がINVALIDのケース

ORA-06508で最も多いのは、呼び出し先パッケージの本体がINVALIDになっているケースです。パッケージ仕様部だけを見てVALIDだと判断すると、原因を見落とします。

package-body-invalid.sql
SELECT object_name, object_type, status
FROM user_objects
WHERE object_name = 'PKG_ORDER'
ORDER BY object_type;

SHOW ERRORS PACKAGE BODY pkg_order;

-- 修正後
ALTER PACKAGE pkg_order COMPILE BODY;

パッケージ本体内で参照しているテーブルや別パッケージが変わった場合、本体だけがINVALIDになることがあります。ALTER PACKAGE ... COMPILE BODY 後もINVALIDなら、USER_ERRORS の先頭エラーから直します。

仕様部と本体の互換性が崩れたケース

パッケージ仕様部のプロシージャ引数や戻り値を変更したのに、本体側や呼び出し元が古いままだと、呼び出し時にORA-06508、PLS-00306、PLS-00905などが連鎖することがあります。

package-spec-body-check.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;

公開仕様を変えた場合は、呼び出し元のパッケージやプロシージャも再コンパイル対象です。依存関係を見て、呼び出される側から呼び出す側へ順に確認します。

依存関係を確認する

呼び出し先が別オブジェクトに依存している場合、さらに下流のオブジェクトが無効になっていることがあります。ORA-06508の直接対象だけでなく、依存先も含めて確認します。

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;

-- 自スキーマのINVALIDをまとめて確認
SELECT object_name, object_type, status
FROM user_objects
WHERE status <> 'VALID'
ORDER BY object_type, object_name;

依存先がINVALIDなら、呼び出し元を再コンパイルする前に、依存先から順にVALIDへ戻します。この考え方は ORA-04063の切り分け と同じです。

シノニムや別スキーマ経由で呼んでいるケース

ORA-06508で意外と見落としやすいのが、シノニム経由で別スキーマのパッケージを呼んでいるケースです。開発環境では APP.PKG_ORDER を見ているつもりでも、本番ではパブリックシノニムや別スキーマの同名オブジェクトに解決され、その実体が存在しない、INVALID、権限不足ということがあります。

synonym-resolution-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;

アプリケーションからだけ失敗する場合は、アプリの接続ユーザーで同じ確認SQLを実行します。作業ユーザーでは正しいオブジェクトに解決されても、アプリユーザーでは別のシノニムを通っている、という差が出るためです。

権限不足やロール権限のケース

開発者ユーザーでは直接SELECTできるのに、パッケージ内では呼び出し先が見えず、結果としてORA-06508になることがあります。PL/SQLオブジェクトでは、ロール経由ではなく直接付与された権限が必要になる場面があります。

direct-grant-check.sql
-- 呼び出し先や参照先への権限を直接付与する例
GRANT EXECUTE ON master_schema.util_pkg TO app_schema;
GRANT SELECT ON master_schema.customers TO app_schema;

-- アプリ実行ユーザーで見えているか確認
SELECT owner, object_name, object_type, status
FROM all_objects
WHERE owner = 'MASTER_SCHEMA'
  AND object_name = 'UTIL_PKG';

権限不足の詳しい考え方は ORA-01031 insufficient privilegesの原因と対処 も参照してください。特に本番では、作業ユーザーではなくアプリケーション接続ユーザーで確認するのが重要です。

既存セッションが古い状態を見ているケース

パッケージを再コンパイルした直後、アプリケーションの既存接続だけでORA-06508が続くことがあります。接続プールが古いパッケージ状態や依存情報を持っている場合、DB側を直した後もアプリ側の接続張り直しが必要になることがあります。

状況 疑うこと 対応
SQL*Plusで新規接続すると成功する 既存アプリ接続の状態が古い 接続プールを再接続
特定セッションだけ失敗する そのセッションが再コンパイル前の状態を保持 セッション切断または再ログイン
再コンパイル直後の初回だけ失敗する パッケージ状態の破棄や再ロード リトライ設計と接続管理を確認

パッケージ状態を持つ処理では ORA-04068 も近い領域です。ORA-06508は呼び出し先を見つけられない/使えない見え方、ORA-04068は既存のパッケージ状態が破棄された見え方です。

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

原因を直したら、対象オブジェクトを明示して再コンパイルします。パッケージは仕様部と本体でコマンドが違うため、どちらを直しているのかを意識します。

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;

OracleのCOMPILE句は、INVALIDかVALIDかに関係なくPL/SQLユニットを明示的に再コンパイルできます。実行時の暗黙コンパイルに任せず、リリース後に明示的に確認しておくと障害を減らせます。

リリース後にORA-06508を出さないための確認

ORA-06508は、リリース直後の疎通確認で見つかることが多いエラーです。パッケージやプロシージャを変更したら、単にDDLが成功したかだけでなく、INVALIDオブジェクトとコンパイルエラーが残っていないかを確認します。

post-release-check.sql
-- リリース後にINVALIDが残っていないか確認
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;

-- パッケージを変更した場合は、代表的な呼び出しを実行して確認
BEGIN
  pkg_order.health_check;
END;
/

本番リリース手順に「USER_OBJECTS のINVALID確認」と「USER_ERRORS の件数確認」を入れておくと、ORA-06508を利用者の操作で初めて発見する流れを避けやすくなります。接続プールを使うアプリでは、パッケージ差し替え後の接続再作成も手順に含めてください。

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

本番で急いで見る場合は、対象名を1つ決めて、存在、状態、エラー、依存関係をまとめて確認します。呼び出し元ではなく、エラーメッセージに出ている呼び出し先の名前を入れてください。

ora-06508-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;

このSQLで ALL_OBJECTS に対象が出ない場合は、スキーマ名違い、シノニム、デプロイ漏れを疑います。対象が出るがINVALIDなら、ALL_ERRORS の先頭エラーを直すのが先です。

ORA-06508と関連エラーの違い

エラー 意味 見るべき場所
ORA-06508 呼び出し先PL/SQLユニットを実行時に利用できない ALL_OBJECTS / ALL_ERRORS
ORA-04063 対象オブジェクトにコンパイルエラーがある USER_ERRORS
PLS-00905 参照しているオブジェクトが無効 対象オブジェクトの再コンパイル
ORA-04068 パッケージ状態が破棄された 既存セッションとパッケージ状態
ORA-04098 トリガーが無効で再検証に失敗 SHOW ERRORS TRIGGER
ORA-01031 権限不足 直接権限と実行ユーザー

トリガーが原因でDML時に落ちる場合は ORA-04098の対処 も確認してください。トリガー内から無効なパッケージを呼んでいる場合、ORA-04098、ORA-04063、ORA-06508が連鎖して見えることがあります。

修正チェックリスト

項目 確認内容 OKの状態
呼び出し先 エラーメッセージ内のオブジェクト名を特定したか スキーマ名・種別まで把握
存在 ALL_OBJECTS に対象が存在するか 想定スキーマに存在
状態 PACKAGE BODYまでVALIDか STATUS = VALID
エラー USER_ERRORS / ALL_ERRORS を確認したか エラー0件
依存先 参照先オブジェクトがVALIDか 依存先もVALID
権限 実行ユーザーに直接権限があるか 必要なEXECUTE/SELECTが直接付与済み
セッション アプリの既存接続が古くないか 接続張り直し後に再現しない

よくある質問

ORA-06508は呼び出し元のSQLを直せば解決しますか?

多くの場合、呼び出し元ではなく呼び出し先の問題です。エラーメッセージに出ているパッケージやプロシージャを ALL_OBJECTSALL_ERRORS で確認してください。

パッケージ仕様部がVALIDなのにORA-06508になります

パッケージ本体がINVALIDの可能性があります。PACKAGE だけでなく PACKAGE BODY の状態も確認してください。

再コンパイルしたのにアプリだけ失敗します

アプリケーションの接続プールが古い状態を見ている可能性があります。新規接続で成功するなら、接続プールの再接続やアプリ再起動を検討します。

USER_ERRORSが空なのに失敗します

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

ORA-04063やPLS-00905も同時に出ています

呼び出し先がINVALIDである可能性が高いです。ORA-06508だけでなく、同時に出ているORA-04063やPLS-00905の対象オブジェクトを直します。

まとめ

ORA-06508は、PL/SQLから呼び出すプログラムユニットをOracleが実行時に利用できなかった時に発生します。削除、INVALID、コンパイルエラー、互換性のない変更、権限不足、古いアプリ接続などが主な原因です。

対応の基本は、呼び出し先オブジェクト名を特定し、ALL_OBJECTS で存在と状態を確認し、USER_ERRORS / ALL_ERRORS で実エラーを読み、依存先と権限を直してから再コンパイルすることです。DB側がVALIDになってもアプリだけ失敗する場合は、接続プールや既存セッションの張り直しも確認してください。

参考

ORA-06508 – Oracle Database Error Help

PLS-00905 – Oracle Database Error Help

COMPILE Clause – Oracle Database PL/SQL Language Reference