【Oracle】ORA-06575の原因と解決方法|Package or function is in an invalid state の直し方

【Oracle】ORA-06575の原因と解決方法|Package or function is in an invalid state の直し方 Oracle

ORA-06575: Package or function string is in an invalid state は、SQLやPL/SQLから呼び出したパッケージ、関数、プロシージャが INVALID 状態で、実行できない時に発生するエラーです。典型例は、CREATE FUNCTIONCREATE PACKAGE BODY がコンパイルエラー付きで作成され、そのまま SELECT function_name(...) のように呼び出したケースです。

Oracle公式のORA-06575説明では、Oracleが関数をコンパイルしようとしたもののエラーを検出したこと、構文エラーや参照オブジェクトへの権限不足を確認することが示されています。つまり、実行文だけでなく、呼び出されるPL/SQLオブジェクトのコンパイル状態と依存関係を確認します。

先に結論
ORA-06575が出たら、まず USER_OBJECTS で対象が INVALID か確認します。次に SHOW ERRORS または USER_ERRORS でコンパイルエラーを見て、修正後に ALTER FUNCTION ... COMPILEALTER PACKAGE ... COMPILE BODY を実行します。コンパイルエラーの読み方は ORA-06550、無効オブジェクト関連は ORA-04063PLS-00905 も合わせて確認します。
スポンサーリンク

ORA-06575とは

ORA-06575は、呼び出し対象のパッケージまたは関数が有効な状態ではないことを示します。SQL文の見た目が正しくても、裏側の関数やパッケージ本体がコンパイルできていなければ実行できません。

状態 意味 確認先
VALID 実行可能な状態 USER_OBJECTS
INVALID 再コンパイルが必要な状態 USER_OBJECTS
コンパイルエラーあり ソースに構文・参照・権限の問題がある USER_ERRORS
依存先が無効 参照している表、ビュー、パッケージが壊れている USER_DEPENDENCIES
権限不足 コンパイル時に必要な直接権限がない GRANT と権限確認

関数やパッケージの作成方法自体は ストアドプロシージャ・ファンクション作成ガイド にまとめています。この記事では、作成後にINVALIDになった時の調べ方と直し方に絞ります。

コンパイルエラー付きで作成された例

次の例では、存在しない列を参照しているため、関数は作成されてもコンパイルエラーを持ちます。この状態で関数を呼ぶとORA-06575になります。

ora06575-created-with-errors.sql
CREATE OR REPLACE FUNCTION get_employee_name(p_employee_id NUMBER)
RETURN VARCHAR2
IS
  l_name employees.employee_name%TYPE;
BEGIN
  SELECT employee_name
  INTO l_name
  FROM employees
  WHERE employee_id = p_employee_id;

  RETURN l_name;
END;
/

-- Warning: Function created with compilation errors.
ora06575-call-invalid-function.sql
SELECT get_employee_name(100)
FROM dual;

-- ORA-06575: Package or function GET_EMPLOYEE_NAME is in an invalid state

このケースでは、呼び出しSQLを直すのではなく、関数のコンパイルエラーを直します。上の例なら、実在する列名に変更する、または参照する表定義に合わせて関数を修正します。

SHOW ERRORSで原因を見る

SQL*PlusやSQLclで直前に作成した関数・パッケージのエラーを見るなら、まず SHOW ERRORS を使います。作成時にWarningだけ出て流してしまった場合も、ここで具体的な行番号とエラーが分かります。

show-errors-function.sql
SHOW ERRORS FUNCTION get_employee_name;

-- LINE/COL ERROR
-- -------- ---------------------------------------------
-- 4/10     PLS-00302: component 'EMPLOYEE_NAME' must be declared

エラー内容が PLS-00201 なら識別子未宣言、PLS-00302 ならコンポーネント未宣言、PLS-00905 ならオブジェクト無効など、別のPL/SQLエラーが根本原因です。未宣言の識別子は PLS-00201 も参考になります。

USER_ERRORSで確認する

画面やツールから原因を追う場合、USER_ERRORS を使うとオブジェクト名、種類、行番号、エラー内容を確認できます。パッケージ本体のエラーなら TYPE = 'PACKAGE BODY' を見ます。別スキーマのオブジェクトを調べる権限がある場合は、ALL_ERRORS も使えます。

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

コンパイルエラーと警告の確認方法は PL/SQLコンパイル時エラーと警告ガイド にもまとめています。CI/CDでPL/SQLをデプロイしている場合は、USER_ERRORS にエラーが残っていないことを確認する運用にすると安全です。

check-all-errors-other-schema.sql
SELECT owner,
       name,
       type,
       line,
       position,
       text
FROM all_errors
WHERE owner = 'APP_USER'
  AND name = 'PKG_EMP'
ORDER BY sequence;

エラー行の前後のソースを確認したい場合は、USER_SOURCE を使います。USER_ERRORS.LINE の前後を表示すると、修正すべき箇所が見つけやすくなります。

check-user-source-around-error.sql
SELECT line,
       text
FROM user_source
WHERE name = 'GET_EMPLOYEE_NAME'
  AND type = 'FUNCTION'
  AND line BETWEEN 1 AND 30
ORDER BY line;

USER_OBJECTSでINVALIDを確認する

対象が本当にINVALIDかどうかは、USER_OBJECTSSTATUS で確認します。関数だけでなく、パッケージ仕様、パッケージ本体、ビュー、トリガーなども同じ考え方で確認できます。

check-user-objects-invalid.sql
SELECT object_name,
       object_type,
       status,
       last_ddl_time
FROM user_objects
WHERE object_name IN ('GET_EMPLOYEE_NAME', 'PKG_EMP')
ORDER BY object_type;
OBJECT_TYPE 見るポイント 再コンパイル例
FUNCTION 単体関数がINVALID ALTER FUNCTION name COMPILE
PROCEDURE 単体プロシージャがINVALID ALTER PROCEDURE name COMPILE
PACKAGE 仕様部がINVALID ALTER PACKAGE name COMPILE
PACKAGE BODY 本体がINVALID ALTER PACKAGE name COMPILE BODY
VIEW 参照元ビューがINVALID ALTER VIEW name COMPILE

再コンパイルする

原因を修正したら、対象オブジェクトを再コンパイルします。ただし、再コンパイルだけで直るのは、依存先が復旧している場合や一時的にINVALIDになっていた場合です。ソースにエラーが残っている場合は、再コンパイルしてもINVALIDのままです。

recompile-invalid-plsql.sql
ALTER FUNCTION get_employee_name COMPILE;

ALTER PACKAGE pkg_emp COMPILE;
ALTER PACKAGE pkg_emp COMPILE BODY;

SELECT object_name, object_type, status
FROM user_objects
WHERE object_name IN ('GET_EMPLOYEE_NAME', 'PKG_EMP');

スキーマ内の無効オブジェクトをまとめて再コンパイルする場合は、DBMS_UTILITY.COMPILE_SCHEMA が使えます。詳細は DBMS_UTILITYガイド を参照してください。

compile-schema-invalid-objects.sql
BEGIN
  DBMS_UTILITY.COMPILE_SCHEMA(
    schema => USER,
    compile_all => FALSE
  );
END;
/

権限不足でINVALIDになる場合

PL/SQLオブジェクトのコンパイルでは、ロール経由の権限ではなく、直接付与された権限が必要になる場面があります。SQLでは参照できるのに、関数やパッケージにするとコンパイルできない場合は、権限不足を疑います。

状況 原因 対処
SQL単体ではSELECTできる ロール経由の権限で見えている 直接GRANTを付与する
パッケージだけINVALID 参照表やビューへの直接権限がない 所有者から直接権限を付与する
本番だけ失敗する 開発と本番で権限差がある 権限差分を確認する
DBリンク経由で失敗する リモート側の権限や名前解決が違う 接続ユーザーとシノニムを確認する
grant-direct-privilege.sql
-- 例: 関数所有者 APP_USER に、参照表への直接権限を付与する
GRANT SELECT ON hr.employees TO app_user;

-- その後、関数やパッケージを再コンパイルする
ALTER FUNCTION app_user.get_employee_name COMPILE;

権限不足は ORA-01031PLS-00201 として見えることもあります。コンパイルエラー本文に「識別子が宣言されていない」と出ても、実際には権限不足で見えていないだけのことがあります。権限まわりの切り分けは ORA-01031の権限不足ガイド も参考になります。

他スキーマ・シノニム経由で呼ぶ場合

本番環境では、APP.GET_PRICE のように他スキーマの関数を呼ぶ、またはシノニム経由で関数を呼ぶ構成があります。この場合、呼び出し元ではなく、実体側の関数やパッケージがINVALIDになっていることがあります。シノニムが指す先、実体オブジェクトの状態、実体スキーマでのコンパイルエラーを分けて確認します。

確認対象 見るSQL ポイント
シノニム USER_SYNONYMS / ALL_SYNONYMS 実体のOWNERとOBJECT_NAMEを確認する
実体オブジェクト ALL_OBJECTS STATUSがVALIDか確認する
実体のエラー ALL_ERRORS 権限があれば別スキーマのエラーも確認する
直接権限 ALL_TAB_PRIVS ロールではなく直接GRANTがあるか確認する
check-synonym-target-invalid.sql
SELECT synonym_name,
       table_owner,
       table_name
FROM user_synonyms
WHERE synonym_name = 'GET_PRICE';

SELECT owner,
       object_name,
       object_type,
       status
FROM all_objects
WHERE owner = 'APP'
  AND object_name = 'GET_PRICE';

依存オブジェクト変更でINVALIDになる場合

参照している表、ビュー、型、パッケージが変更されると、依存する関数やパッケージがINVALIDになることがあります。列名変更、型変更、ビュー再作成、パッケージ仕様変更の後にORA-06575が出る場合は、依存関係を確認します。

check-user-dependencies.sql
SELECT name,
       type,
       referenced_name,
       referenced_type
FROM user_dependencies
WHERE name = 'GET_EMPLOYEE_NAME'
ORDER BY referenced_type, referenced_name;

依存先のビューやパッケージ本体にエラーがある場合、ORA-06575の手前で ORA-04063ORA-06508 が関係していることもあります。呼び出されるオブジェクトだけでなく、依存先まで順に確認します。

パッケージの場合の確認ポイント

パッケージでは、仕様部と本体が分かれているため、どちらがINVALIDなのかを分けて確認します。仕様部が変わると依存オブジェクトへの影響が大きく、本体だけの修正なら影響範囲は比較的小さくなります。

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

SELECT line, position, text
FROM user_errors
WHERE name = 'PKG_EMP'
ORDER BY sequence;

パッケージ仕様と本体の不一致なら、PLS-00323PLS-00905 が出ることがあります。パッケージ本体のコンパイルエラーを直してから、再度呼び出しSQLを実行します。

関連エラーとの違い

エラー 意味 主な確認先 関連記事
ORA-06575 パッケージ/関数がINVALID状態 USER_OBJECTS、USER_ERRORS この記事
ORA-06550 PL/SQLコンパイル/実行時の構文・宣言エラー エラー行、PLSエラー ORA-06550
ORA-04063 ビュー/パッケージ本体などにエラーあり USER_ERRORS、依存先 ORA-04063
ORA-06508 呼び出すプログラムユニットが見つからない/使えない 依存先、再コンパイル ORA-06508
PLS-00905 オブジェクトが無効 対象オブジェクトのエラー PLS-00905

調査手順

ORA-06575は、エラーが出たSQLだけを見ると原因を見落としやすいです。次の順で確認すると、INVALIDの原因までたどりやすくなります。

ora06575-investigation-flow.sql
-- 1. 対象オブジェクトの状態を確認
SELECT object_name, object_type, status
FROM user_objects
WHERE object_name = 'GET_EMPLOYEE_NAME';

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

-- 3. 修正後に再コンパイル
ALTER FUNCTION get_employee_name COMPILE;

-- 4. VALIDになったことを確認
SELECT object_name, object_type, status
FROM user_objects
WHERE object_name = 'GET_EMPLOYEE_NAME';

よくある原因と対処一覧

原因 症状 対処
関数内の構文エラー created with compilation errors後にORA-06575 SHOW ERRORSで行を直す
列名・型名の間違い PLS-00302やPLS-00201が出る 正しい列名・型名に修正
参照権限不足 SQLでは見えるがPL/SQLで失敗 直接GRANTを付与
依存先オブジェクトがINVALID 再コンパイルしても直らない 依存先のUSER_ERRORSを確認
パッケージ仕様と本体の不一致 PACKAGE BODYがINVALID 仕様と本体を揃える
デプロイ順序ミス 本番反映直後だけ失敗 依存先から順にコンパイル

チェックリスト

項目 OKの状態
USER_OBJECTSで対象を確認した STATUS = VALID になっている
USER_ERRORSを確認した 対象オブジェクトのエラーが残っていない
SHOW ERRORSを確認した 直前作成オブジェクトのエラーを把握している
依存先も確認した 参照ビュー・パッケージ・型がVALID
権限を確認した 必要な表・ビューへの直接権限がある
再コンパイル後に再実行した 同じSQLでORA-06575が消えている

よくある質問

SELECT文が正しいのにORA-06575になります

SELECT文の構文ではなく、SELECT内で呼んでいる関数がINVALIDの可能性があります。関数側の USER_ERRORS を確認してください。

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

原因が一時的なINVALIDだけなら直ることがあります。ソースエラーや権限不足が残っている場合は、再コンパイルしてもINVALIDのままです。

ロールで権限があるのにコンパイルできません

PL/SQLのコンパイルでは直接付与された権限が必要になることがあります。所有者から対象スキーマへ直接GRANTして再コンパイルします。

本番デプロイ後に急に出ました

デプロイ順序、依存先オブジェクトの変更、権限差分を確認します。依存先をVALIDにしてから、関数やパッケージを再コンパイルします。

まとめ

ORA-06575は、パッケージや関数がINVALID状態で実行できない時に発生します。呼び出しSQLだけではなく、対象オブジェクトの USER_OBJECTSUSER_ERRORS、依存先、権限を確認することが重要です。

まず SHOW ERRORSUSER_ERRORS で根本のコンパイルエラーを直し、必要に応じて ALTER FUNCTION ... COMPILEALTER PACKAGE ... COMPILE BODYDBMS_UTILITY.COMPILE_SCHEMA を使います。再コンパイルだけで済ませず、なぜINVALIDになったかまで確認すると再発を防ぎやすくなります。

参考

ORA-06575 – Oracle Database Error Help

PL/SQL Subprograms – Oracle Database PL/SQL Language Reference

USER_OBJECTS – Oracle Database Reference