【Oracle】ORA-04063の原因と解決方法|view/package body has errors・オブジェクトにエラーがあります

【Oracle】ORA-04063の原因と解決方法|view/package body has errors・オブジェクトにエラーがあります Oracle

ORA-04063: string has errors は、Oracleのビュー、パッケージ、プロシージャ、ファンクション、トリガー、型などのオブジェクトにエラーが残っていて、実行または参照できない時に発生するエラーです。

メッセージは短いですが、ORA-04063そのものは「本当の原因」ではなく、対象オブジェクトがコンパイルできていない、または参照先の変更で無効になっていることを知らせる入口です。実際に直すべき箇所は、USER_ERRORSSHOW ERRORS に出ている下位のエラーです。

先に結論
ORA-04063が出たら、まずエラーメッセージ内のオブジェクト名を確認します。次に USER_ERRORS または SHOW ERRORS でコンパイルエラーの本文を読み、参照先のテーブル・列・パッケージ、権限、依存オブジェクトを直してから再コンパイルします。VIEWなら ALTER VIEW ... COMPILE、PACKAGEなら ALTER PACKAGE ... COMPILE が基本です。
スポンサーリンク

ORA-04063とは

Oracle公式の説明では、ORA-04063はストアドプロシージャの実行やビューの利用時に、対象オブジェクトにエラーがある場合に発生するエラーです。ストアドプロシージャなら構文エラーや存在しないプロシージャ参照、ビューなら定義SQL内の存在しない表参照などが原因になります。

実務では、次のような形でよく出ます。

表示例 よくある意味 最初に見る場所
ORA-04063: view "APP.V_ORDERS" has errors ビュー定義が壊れている USER_ERRORS / USER_VIEWS
ORA-04063: package body "APP.PKG_ORDER" has errors パッケージ本体がコンパイルできていない SHOW ERRORS PACKAGE BODY
ORA-04063: procedure "APP.P_SYNC" has errors プロシージャが無効 SHOW ERRORS PROCEDURE
ORA-04063: table "APP.T_DOC" has errors 型や依存オブジェクトの不整合が絡むことがある USER_OBJECTS / USER_ERRORS

トリガーが無効でDML時に落ちる場合は ORA-04098の原因と解決方法 が近い話です。ORA-04063は、トリガーに限らずビューやPL/SQLオブジェクト全般で起きる点が違います。

まず確認する順番

ORA-04063は、手当たり次第に再コンパイルするより、次の順番で見ると早いです。特に本番障害では、対象オブジェクト、実エラー、依存先の3点を切り分けるのが大切です。

順番 確認すること 使うSQL・コマンド
1 メッセージに出たオブジェクト名と種類 ORA-04063: view/package body ...
2 オブジェクトの状態 USER_OBJECTS
3 コンパイルエラー本文 USER_ERRORS / SHOW ERRORS
4 参照先オブジェクト USER_DEPENDENCIES
5 権限不足やロール権限の影響 USER_TAB_PRIVS / SESSION_ROLES
6 修正後の再コンパイル ALTER ... COMPILE

対象オブジェクトの状態を確認する

まず、エラーに出ているオブジェクトが VALIDINVALID かを確認します。大文字で格納されることが多いため、通常は大文字名で検索します。

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

STATUSINVALID なら、オブジェクトの定義または参照先に問題があります。VALID に見えるのにORA-04063が続く場合は、別スキーマの同名オブジェクト、シノニム、実行ユーザーの違い、または依存先オブジェクトの状態を確認します。

USER_ERRORSで本当の原因を見る

ORA-04063の調査で一番大事なのは、USER_ERRORS を読むことです。ここにはコンパイル時の行番号、列番号、エラー本文が残ります。複数行ある場合は、最初のエラーが後続エラーを連鎖させていることが多いです。

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

他スキーマの参照可能なオブジェクトまで見る場合は ALL_ERRORS、DBA権限がある場合は DBA_ERRORS を使います。PL/SQLのコンパイルエラー全般は SHOW ERRORS・USER_ERRORSの使い方 でも詳しく整理しています。

SHOW ERRORSを使う場合

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

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

GUIツールやアプリケーションから調査する場合は、SHOW ERRORS より USER_ERRORS を直接SELECTする方が扱いやすいです。リリース後チェックを自動化する場合も、USER_ERRORS の件数を確認する形にすると安定します。

VIEW has errors の直し方

view has errors の場合は、ビュー定義のSELECT文が現在のテーブル定義や権限と合っていないことが多いです。列名変更、参照テーブルの削除、型変更、参照先ビューの無効化、権限不足を疑います。

view-investigation.sql
-- ビュー定義を確認
SELECT text
FROM user_views
WHERE view_name = 'V_ORDERS';

-- コンパイルエラーを確認
SELECT line, position, text
FROM user_errors
WHERE name = 'V_ORDERS'
ORDER BY sequence;

-- 修正後に再コンパイル
ALTER VIEW v_orders COMPILE;

単純な参照先変更なら ALTER VIEW ... COMPILE でVALIDに戻ります。ただし、ビューのSELECT定義そのものが古い場合は、CREATE OR REPLACE VIEW で定義を直す必要があります。

PACKAGE BODY has errors の直し方

package body has errors の場合は、パッケージ仕様部ではなく本体側にコンパイルエラーが残っています。よくある原因は、仕様部と本体の引数不一致、存在しない表・列・型の参照、ロール経由権限、呼び出し先プロシージャの変更です。

package-body-errors.sql
SHOW ERRORS PACKAGE BODY pkg_order;

SELECT line, position, text
FROM user_errors
WHERE name = 'PKG_ORDER'
  AND type = 'PACKAGE BODY'
ORDER BY sequence;

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

パッケージ変数を持つパッケージを再コンパイルした後、既存セッション側で状態破棄が絡む場合は ORA-04068の解説 も確認してください。ORA-04063はコンパイルエラー、ORA-04068はパッケージ状態の破棄が中心です。

権限不足が原因のパターン

開発者がSQL Developerで直接SELECTできるのに、パッケージやビューの中では失敗することがあります。この場合、ロール経由の権限で見えているだけで、ストアドオブジェクトのコンパイル時に必要な直接権限が不足している可能性があります。

grant-direct-privilege.sql
-- NGになりやすい例: ロール経由のSELECT権限だけでコンパイルしている
-- 対応: オブジェクト所有者から、パッケージ所有者へ直接GRANTする
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の原因と対処 も参考になります。特にPL/SQL内では、ロール権限と直接付与権限の違いを意識してください。

依存オブジェクトを確認する

ORA-04063は、対象オブジェクト自体だけでなく、参照先が壊れているせいで発生することもあります。ビューが別ビューを参照している、パッケージが別パッケージを呼んでいる、型やシノニムを経由している場合は、依存関係を確認します。

dependencies.sql
SELECT name,
       type,
       referenced_owner,
       referenced_name,
       referenced_type
FROM user_dependencies
WHERE name IN ('V_ORDERS', 'PKG_ORDER')
ORDER BY name, referenced_type, referenced_name;

-- 参照先の無効オブジェクトも確認
SELECT object_name, object_type, status
FROM user_objects
WHERE status <> 'VALID'
ORDER BY object_type, object_name;

依存先がINVALIDなら、先に依存先を修正・再コンパイルします。下流のオブジェクトから直すより、参照される側から順にVALIDへ戻す方が原因を追いやすくなります。

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

原因を直したら、対象オブジェクトを明示的に再コンパイルします。再コンパイルだけで直る場合もありますが、エラー本文が残っている限りVALIDには戻りません。

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

-- 再確認
SELECT object_name, object_type, status
FROM user_objects
WHERE object_name IN ('V_ORDERS', 'PKG_ORDER', 'P_SYNC')
ORDER BY object_type, object_name;

トリガーの再コンパイルや無効化の判断が必要な場合は、Oracleトリガーの基本と有効化・無効化 も確認してください。

よくある原因と対処一覧

原因 出やすいエラー 対処
参照先テーブルや列が変更された ORA-00904 / ORA-00942 定義SQLやPL/SQL本文を現行スキーマに合わせる
パッケージ仕様部と本体が不一致 PLS-00323 / PLS-00306 引数、戻り値、公開手続きの宣言を合わせる
ロール経由の権限しかない ORA-00942 / PLS-00201 所有者へ直接GRANTする
参照先オブジェクトがINVALID ORA-04063 の連鎖 依存先から順にコンパイルする
シノニムが古い参照先を向いている ORA-04043 / ORA-00942 シノニム定義と実体オブジェクトを確認する
型やパッケージをリリースで差し替えた ORA-04063 / ORA-04068 依存オブジェクトと既存セッションへの影響を確認する

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

本番で急いで切り分ける場合は、次のように状態、エラー、依存関係をまとめて確認します。オブジェクト名だけ差し替えて使える形にしておくと、障害時の初動が早くなります。

ora-04063-investigation.sql
DEFINE obj_name = 'PKG_ORDER'

SELECT object_name, object_type, status, last_ddl_time
FROM user_objects
WHERE object_name = UPPER('&obj_name');

SELECT type, sequence, line, position, text
FROM user_errors
WHERE name = UPPER('&obj_name')
ORDER BY 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;

この結果で USER_ERRORS が空なのにORA-04063が続く場合は、実行ユーザーが見ているオブジェクトが想定と違う、別スキーマのオブジェクトを参照している、シノニム経由で古い実体に向いている、という方向も確認します。

USER_ERRORSが空に見える場合

現場で迷いやすいのが、ORA-04063は出ているのに自分の USER_ERRORS には何も出ないケースです。これは、エラーを持っている実体が自スキーマではない、シノニム経由で別オブジェクトを見ている、または調査ユーザーと実行ユーザーが違う時に起きます。

all-errors-and-synonyms.sql
-- 他スキーマの参照可能なエラーを確認
SELECT owner, name, type, line, position, text
FROM all_errors
WHERE name IN ('V_ORDERS', 'PKG_ORDER')
ORDER BY owner, name, type, sequence;

-- シノニムがどの実体を向いているか確認
SELECT owner, synonym_name, table_owner, table_name, db_link
FROM all_synonyms
WHERE synonym_name IN ('V_ORDERS', 'PKG_ORDER')
ORDER BY owner, synonym_name;

-- 実体オブジェクトの状態を確認
SELECT owner, object_name, object_type, status
FROM all_objects
WHERE object_name IN ('V_ORDERS', 'PKG_ORDER')
ORDER BY owner, object_type, object_name;

アプリケーション経由でだけORA-04063が出る場合は、アプリの接続ユーザーで同じSQLを実行して確認します。開発者ユーザーでは見えていても、実行ユーザーには直接権限がない、別のシノニムを解決している、という差が出るためです。

ORA-06508やPLS-00905と一緒に出る場合

ORA-04063は、ORA-06508: PL/SQL: could not find program unit being calledPLS-00905: object is invalid と一緒に出ることがあります。この場合も、呼び出し元のSQLだけを直すのではなく、呼び出される側のパッケージ、プロシージャ、ファンクションがVALIDかを確認します。

ora-06508-pls-00905-check.sql
-- 呼び出される側の状態を見る
SELECT owner, object_name, object_type, status
FROM all_objects
WHERE object_name IN ('PKG_ORDER', 'P_SYNC', 'F_CALC_TAX')
ORDER BY owner, object_type, object_name;

-- エラー本文を見る
SELECT owner, name, type, line, position, text
FROM all_errors
WHERE name IN ('PKG_ORDER', 'P_SYNC', 'F_CALC_TAX')
ORDER BY owner, name, type, sequence;

-- 修正後、所有者スキーマで再コンパイルする
ALTER PACKAGE pkg_order COMPILE BODY;
ALTER PROCEDURE p_sync COMPILE;
ALTER FUNCTION f_calc_tax COMPILE;

ORA-06508は「呼び出すべきプログラムユニットが使えない」という実行時の見え方です。根本原因がORA-04063やPLS-00905なら、呼び出し先オブジェクトのコンパイルエラーを消すことが先です。

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

エラー 意味 見るべき場所
ORA-04063 オブジェクトにエラーがある USER_ERRORS と依存関係
ORA-04098 トリガーが無効で再検証に失敗 SHOW ERRORS TRIGGER
ORA-04068 パッケージ状態が破棄された 再コンパイル後の既存セッション
ORA-06508 呼び出すPL/SQLユニットが見つからない、または使えない 呼び出し先の ALL_OBJECTSALL_ERRORS
ORA-06550 PL/SQLの実行・コンパイル時エラーの入口 続く PLS- エラー
PLS-00201 識別子が宣言されていない オブジェクト名、権限、スコープ
PLS-00905 参照しているオブジェクトが無効 対象オブジェクトのコンパイルエラー
ORA-01031 権限不足 直接GRANTと実行ユーザー

ORA-04063の下に ORA-06550PLS-00201 が続くこともあります。その場合は、ORA-04063だけを見ず、後続のPL/SQLエラー本文を読みます。例外処理やエラー番号の扱いは PL/SQL例外処理の基本 も参考になります。

修正チェックリスト

項目 確認内容 OKの状態
対象 エラーメッセージのオブジェクト名と実際の調査対象が一致しているか スキーマ名・種別まで一致
状態 USER_OBJECTS.STATUS を確認したか VALID
実エラー USER_ERRORS の先頭エラーを読んだか エラー0件
参照先 テーブル、列、型、別パッケージが存在するか 参照先もVALID
権限 ロールではなく直接権限があるか 必要なSELECT/EXECUTE等が直接付与済み
再コンパイル 修正後に ALTER ... COMPILE したか 再実行してもORA-04063が出ない

よくある質問

ALTER … COMPILEだけで直りますか?

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

USER_ERRORSが空なのにORA-04063が出ます

調査しているスキーマやオブジェクト名が違う可能性があります。エラーに出ているスキーマ名、シノニムの参照先、実行ユーザーを確認してください。必要に応じて ALL_ERRORSDBA_ERRORS も見ます。

ビューをSELECTしただけでORA-04063になるのはなぜですか?

ビュー定義の中で参照しているテーブル、列、関数、別ビューなどが現在の状態と合っていないためです。USER_VIEWSUSER_ERRORS を確認し、定義を直してから再コンパイルします。

パッケージ仕様部と本体はどちらを直しますか?

package body has errors なら本体側を見ます。ただし、仕様部の宣言と本体の実装がずれている場合は、仕様部と本体の両方を合わせる必要があります。

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

無効なビューやパッケージを使う処理を止める、参照先を戻す、直近リリースを切り戻すなどの選択肢はあります。ただし根本対応は、USER_ERRORS に出ているコンパイルエラーを解消してVALIDに戻すことです。

まとめ

ORA-04063は、ビューやパッケージなどのオブジェクトにエラーがあり、実行または参照できない時に発生します。エラーメッセージだけでは原因が抽象的なので、まず対象オブジェクト名と種別を確認し、USER_ERRORSSHOW ERRORS で実際のコンパイルエラーを読みます。

よくある原因は、参照先テーブル・列の変更、パッケージ仕様部と本体の不一致、直接権限不足、依存オブジェクトの無効化です。修正後は ALTER VIEW ... COMPILEALTER PACKAGE ... COMPILE BODY で再コンパイルし、USER_OBJECTS.STATUSUSER_ERRORS を再確認してください。

参考

ORA-04063 – Oracle Database Error Help

ALL_ERRORS – Oracle Database Reference

ALTER VIEW – Oracle SQL Language Reference

ALTER PACKAGE – Oracle SQL Language Reference