【完全ガイド】PLS-00302: component must be declared の原因と解決方法|PLS-00201 との違い・シノニム・SPEC 未宣言 徹底解説

【完全ガイド】PLS-00302: component must be declared の原因と解決方法|PLS-00201 との違い・シノニム・SPEC 未宣言 徹底解説

Oracle PL/SQL 開発者が日常的に遭遇するコンパイル/実行時エラー:

BEGIN
  hr.emp_pkg.get_salary(100);
END;
/
*
ERROR at line 2:
ORA-06550: line 2, column 10:
PLS-00302: component 'GET_SALARY' must be declared
ORA-06550: line 2, column 3:
PL/SQL: Statement ignored

**「コンポーネントが宣言されていない」**というシンプルなメッセージ。Oracle のパッケージ・スキーマ構造を理解する上で重要なエラーです:

  • SCHEMA.OBJECT or PACKAGE.MEMBERメンバー部分が見つからない
  • PLS-00201 (identifier) とは微妙に異なる
  • PL/SQL コンパイル時に発生
  • パッケージ仕様書 (SPEC) に未宣言のメンバーへのアクセス
  • スキーマ違い + シノニム不足の典型

このエラーの本質は、ドット表記の左側(親)は解決されたが、右側(子・コンポーネント)が見つからない:

SCHEMA.PACKAGE.PROCEDURE
  ↑        ↑         ↑
 見えた   見えた   見えない → PLS-00302
                              (PROCEDURE 部分)

my_pkg.some_func
  ↑        ↑
見えた   見えない → PLS-00302
          (some_func 部分)
目次

PLS-00201 vs PLS-00302 の決定的違い

混同しやすい姉妹エラー:

PLS-00201: identifier 'X' must be declared
  → X 全体が見えない
  → 「変数」「オブジェクト」「シノニム」等が未定義

PLS-00302: component 'Y' must be declared
  → Y は SCHEMA.Y or PACKAGE.Y の Y 部分
  → 親 (SCHEMA/PACKAGE) は見えたが Y が見えない

現場で最も典型的なパターン:

  • メンバー名のスペルミス
  • PACKAGE BODY にのみ定義(SPEC 未宣言)
  • private メンバーへの外部アクセス
  • スキーマ違いSCHEMA_A.pkg.funcSCHEMA_B から呼び出し)
  • GRANT EXECUTE はあるが SYNONYM なし(両方必要)
  • 大文字小文字(引用符付き識別子)
  • INVALID パッケージ
  • Object Type のメソッド不在
  • RECORD 型のフィールド不在
  • オーバーロード解決失敗

さらに、特殊環境での典型パターン:

  • DataGrip / VSCode のデバッガで PLS-00302
  • Crystal Reports の schema prefix 強制で PLS-00302
  • Oracle パッチ後の突然の発生

多くの日本語記事が「メンバー名を確認せよ」で終わりますが、実務では:

  • PLS-00201 との厳密な違い
  • GRANT EXECUTE だけでは不十分(シノニム必要)
  • ALL_PROCEDURES / ALL_ARGUMENTS による診断
  • パッケージ SPEC vs BODY の関係
  • CREATE SYNONYM の必要性
  • PUBLIC SYNONYM vs プライベート SYNONYM
  • DataGrip / VSCode デバッガの特殊挙動
  • Crystal Reports の schema prefix 問題
  • Rails ActiveRecord からのストアド呼び出し
  • Oracle パッチ後の突然発生 への対処

さらに、Oracle の権限モデルの罠として、GRANT EXECUTE を付与してもシノニムがないと PLS-00302 が発生するケース:

-- IS ユーザーで POKUS プロシージャ作成
CREATE PROCEDURE pokus AS BEGIN NULL; END;

-- BOB に GRANT EXECUTE
GRANT EXECUTE ON pokus TO bob;

-- BOB から呼び出し
BEGIN pokus; END;
-- → PLS-00302: component 'POKUS' must be declared

-- シノニム作成が必要
CREATE SYNONYM bob.pokus FOR is.pokus;
BEGIN pokus; END;
-- → OK

**「GRANT EXECUTE だけでは足りない」**という事実は、多くの開発者を悩ませます。

本記事では、PLS-00302: component must be declared完全な原因と解決方法を、リファレンスとして実用的に整理します。PLS-00201 との違い、10大発生パターン、6つの解決策、シノニム / SPEC / private メンバー、Rails/Java/Python 対応、実践シナリオ、FAQまで完全網羅。この1本で PLS-00302 を根本から解決できるようになります。


結論:スペル・SPEC 宣言・シノニム確認

時間がない方向けに、最速の対処を先に示します。

エラーメッセージの読み方

PLS-00302: component 'X' must be declared
                      ↑
              コンポーネント名(メンバー)

= SCHEMA.X or PACKAGE.X の X が見つからない
  親(SCHEMA/PACKAGE)は解決できた

最速の診断

-- ① オブジェクト存在確認
SELECT owner, object_name, object_type, status
FROM all_objects
WHERE object_name = UPPER('X') OR object_name LIKE '%X%';

-- ② パッケージ内メンバー一覧
SELECT procedure_name, overload
FROM all_procedures
WHERE owner = 'SCHEMA' AND object_name = 'PACKAGE';

-- ③ プロシージャの引数
SELECT position, argument_name, data_type
FROM all_arguments
WHERE owner = 'SCHEMA'
  AND object_name = 'PROC'
ORDER BY position;

-- ④ シノニム確認
SELECT * FROM all_synonyms 
WHERE synonym_name = UPPER('X');

6つの解決策

#手法使う場面
スペル修正タイポ
仕様書 (SPEC) 追加BODY 定義漏れ
シノニム作成スキーマ違い
PUBLIC SYNONYM全体公開
パッケージ再コンパイルINVALID
オーバーロード確認引数不一致

姉妹エラー3種

エラー意味
PLS-00201識別子全体が未宣言
PLS-00302コンポーネント(メンバー)未宣言
PLS-00306引数の数/型が不一致
PLS-00323subprogram not declared

詳細は以下で解説します。


Oracle のドット表記の仕組み

3 レベルのドット表記

SCHEMA.PACKAGE.PROCEDURE
  ↑        ↑         ↑
スキーマ  パッケージ プロシージャ

例: hr.emp_pkg.get_salary

解決順序

Oracle は左から順に解決:

1. SCHEMA を探す
   → 見つからない → PLS-00201
2. PACKAGE を探す(SCHEMA 内で)
   → 見つからない → PLS-00302 (or PLS-00201)
3. PROCEDURE を探す(PACKAGE 内で)
   → 見つからない → PLS-00302

代表的なパターン

hr.emp_pkg.get_salary

PLS-00201: hr が見えない PLS-00302: hr.emp_pkg は見えたが get_salary が見えない PLS-00306: get_salary は見えたが引数が違う


【原因①】メンバー名のスペルミス(最頻出)

症状

CREATE PACKAGE emp_pkg IS
  PROCEDURE get_salary(p_id NUMBER);
END;
/

BEGIN
  emp_pkg.get_salery(100);   -- ← タイポ (salary → salery)
END;
/
-- PLS-00302: component 'GET_SALERY' must be declared

解決

スペル修正、IDE のオートコンプリート活用:

BEGIN
  emp_pkg.get_salary(100);
END;
/

予防: 命名規則統一、IDE 利用。


【原因②】PACKAGE BODY のみに定義(SPEC 未宣言)

症状(超典型)

-- 仕様書 (SPEC)
CREATE PACKAGE emp_pkg IS
  PROCEDURE get_salary(p_id NUMBER);
  -- helper_func は宣言されていない
END;
/

-- 本体 (BODY)
CREATE PACKAGE BODY emp_pkg IS
  FUNCTION helper_func RETURN NUMBER IS   -- BODY 内のみ
  BEGIN
    RETURN 100;
  END;
  
  PROCEDURE get_salary(p_id NUMBER) IS
  BEGIN
    NULL;
  END;
END;
/

-- 外部から呼び出し
BEGIN
  DBMS_OUTPUT.PUT_LINE(emp_pkg.helper_func);
  -- PLS-00302: component 'HELPER_FUNC' must be declared
END;
/

理由: helper_func はパッケージ内 private、外部から見えない。

解決A: SPEC に宣言追加(public 化)

CREATE OR REPLACE PACKAGE emp_pkg IS
  PROCEDURE get_salary(p_id NUMBER);
  FUNCTION helper_func RETURN NUMBER;   -- ← 追加
END;
/

解決B: private のままにする

外部から呼び出さないならそのままで OK、パッケージ内部からのみ使う。


【原因③】private メンバーへの外部アクセス

シナリオ

-- SPEC には proc_a のみ
CREATE PACKAGE my_pkg IS
  PROCEDURE proc_a;
END;
/

-- BODY に private proc_b と public proc_a
CREATE PACKAGE BODY my_pkg IS
  PROCEDURE proc_b IS   -- private
  BEGIN
    NULL;
  END;
  
  PROCEDURE proc_a IS
  BEGIN
    proc_b;   -- 内部からは OK
  END;
END;
/

-- 外部から proc_b を直接呼び出し
BEGIN
  my_pkg.proc_b;   -- PLS-00302
END;
/

解決

A. private のまま + proc_a 経由で呼び出し(推奨):

BEGIN
  my_pkg.proc_a;   -- proc_a が内部で proc_b 呼び出し
END;
/

B. public 化:

CREATE OR REPLACE PACKAGE my_pkg IS
  PROCEDURE proc_a;
  PROCEDURE proc_b;   -- ← 追加
END;
/

【原因④】スキーマ違い + シノニム不足

シナリオ(超典型)

-- HR ユーザーで emp_pkg 作成
CREATE PACKAGE hr.emp_pkg IS
  PROCEDURE get_data;
END;
/

GRANT EXECUTE ON hr.emp_pkg TO scott;

-- SCOTT ユーザーから呼び出し
CONNECT scott/tiger

BEGIN
  emp_pkg.get_data;   -- PLS-00302
  -- SCOTT スキーマに emp_pkg が見えない
END;
/

解決A: シノニム作成(推奨)

-- SCOTT で
CREATE SYNONYM emp_pkg FOR hr.emp_pkg;

-- または PUBLIC SYNONYM
CREATE PUBLIC SYNONYM emp_pkg FOR hr.emp_pkg;

BEGIN
  emp_pkg.get_data;   -- OK
END;
/

解決B: スキーマプレフィックス

BEGIN
  hr.emp_pkg.get_data;   -- OK
END;
/

権限系は ORA-01031: insufficient privileges の記事、PLS-00201: identifier must be declared の記事も参照してください。


【原因⑤】GRANT EXECUTE だけでは不十分

症状(Oracle Community 実例)

-- IS ユーザーで
CREATE PROCEDURE pokus AS
BEGIN
  DBMS_OUTPUT.PUT_LINE('Hello');
END;
/

GRANT EXECUTE ON pokus TO bob;

-- BOB から
CONNECT bob/pw
BEGIN pokus; END;
-- PLS-00302: component 'POKUS' must be declared

-- シノニム作成が必要
CREATE SYNONYM bob.pokus FOR is.pokus;
BEGIN pokus; END;
-- OK

なぜ

Oracle の名前解決:

  • BEGIN pokus; END; は現スキーマ内で pokus を探す
  • BOB スキーマに pokus は存在しない
  • GRANT EXECUTE = 実行権名前解決には SYNONYM 必要

解決

A. プライベート SYNONYM:

CREATE SYNONYM bob.pokus FOR is.pokus;

B. PUBLIC SYNONYM:

CREATE PUBLIC SYNONYM pokus FOR is.pokus;

C. 明示プレフィックス:

BEGIN is.pokus; END;

【原因⑥】大文字小文字(引用符付き識別子)

シナリオ

-- Rails マイグレーションで作成された関数
CREATE FUNCTION "getUserName" RETURN VARCHAR2 IS
BEGIN
  RETURN 'John';
END;
/
-- 引用符付き = case-sensitive

BEGIN
  DBMS_OUTPUT.PUT_LINE(getUserName);   
  -- 実は GETUSERNAME を探す → 見つからない → PLS-00201/00302
END;
/

解決

A. 引用符付きで呼び出し:

BEGIN
  DBMS_OUTPUT.PUT_LINE("getUserName");
END;
/

B. リネーム(推奨):

DROP FUNCTION "getUserName";
CREATE FUNCTION get_user_name RETURN VARCHAR2 IS ...;

【原因⑦】INVALID パッケージ

シナリオ

-- パッケージが INVALID
SELECT status FROM user_objects WHERE object_name = 'MY_PKG';
-- INVALID

BEGIN
  my_pkg.some_proc;
END;
/
-- PLS-00302 (INVALID なため見えないと判定)

解決

ALTER PACKAGE my_pkg COMPILE;
SHOW ERRORS;

-- または一括
BEGIN
  UTL_RECOMP.recomp_parallel(4);
END;
/

INVALID 関連は PLS-00905: object is invalid の記事も参照してください。


【原因⑧】Object Type のメソッド不在

シナリオ

CREATE TYPE addr_t AS OBJECT (
  street VARCHAR2(100),
  MEMBER FUNCTION format RETURN VARCHAR2
);
/

DECLARE
  v addr_t := addr_t('Main St');
BEGIN
  DBMS_OUTPUT.PUT_LINE(v.non_existent_method);
  -- PLS-00302
END;
/

解決

メソッドを Object Type に追加、または呼び出し方法確認。


【原因⑨】RECORD 型フィールド不在

シナリオ

DECLARE
  TYPE person_rec IS RECORD (
    name VARCHAR2(100),
    age NUMBER
  );
  v person_rec;
BEGIN
  v.address := 'Tokyo';   -- address フィールドなし
  -- PLS-00302: component 'ADDRESS' must be declared
END;
/

解決

RECORD 定義にフィールド追加:

TYPE person_rec IS RECORD (
  name VARCHAR2(100),
  age NUMBER,
  address VARCHAR2(200)   -- ← 追加
);

【原因⑩】DataGrip / VSCode デバッガ

症状(実例)

DataGrip / VSCode で PL/SQL デバッグ
→ PLS-00302 error message
→ debugger stops

SQL Developer では正常動作

原因

デバッガ内部の PL/SQL 呼び出しが特殊なコンテキストで実行され、パッケージメンバーが見つからない。

解決

A. デバッグ権限確認:

GRANT DEBUG CONNECT SESSION TO student;
GRANT DEBUG ANY PROCEDURE TO student;

B. SQL Developer で代替C. IDE 側の設定確認(DataGrip の Oracle Driver)。


診断ツール完全リファレンス

ALL_PROCEDURES

-- パッケージ内メンバー
SELECT procedure_name, overload, aggregate, pipelined, 
       impltypeschema, deterministic
FROM all_procedures
WHERE owner = 'SCHEMA' AND object_name = 'PACKAGE';

ALL_ARGUMENTS

-- プロシージャ/ファンクションのシグネチャ
SELECT position, argument_name, data_type, in_out
FROM all_arguments
WHERE owner = 'SCHEMA'
  AND package_name = 'PACKAGE'
  AND object_name = 'PROC'
ORDER BY overload, position;

ALL_OBJECTS

-- オブジェクト存在確認
SELECT owner, object_name, object_type, status, last_ddl_time
FROM all_objects
WHERE object_name = 'X' OR object_name LIKE '%X%';

ALL_SYNONYMS

-- シノニム確認
SELECT owner, synonym_name, table_owner, table_name
FROM all_synonyms
WHERE synonym_name = 'X'
   OR table_name = 'X';

USER_ERRORS

-- パッケージのコンパイルエラー
SELECT line, position, text
FROM user_errors
WHERE name = 'MY_PKG'
ORDER BY sequence;

6つの解決策 完全リファレンス

解決策① スペル修正

IDE のオートコンプリート活用:

  • SQL Developer
  • DataGrip / IntelliJ IDEA
  • VSCode + PLSQL Language Server

解決策② 仕様書 (SPEC) 追加

-- BEFORE: SPEC に helper_func なし
CREATE PACKAGE my_pkg IS
  PROCEDURE proc_a;
END;
/

-- AFTER: SPEC に追加
CREATE OR REPLACE PACKAGE my_pkg IS
  PROCEDURE proc_a;
  FUNCTION helper_func RETURN NUMBER;   -- ← 追加
END;
/

解決策③ シノニム作成

-- プライベート
CREATE SYNONYM emp_pkg FOR hr.emp_pkg;

-- パブリック(全ユーザー用)
CREATE PUBLIC SYNONYM emp_pkg FOR hr.emp_pkg;

解決策④ 明示プレフィックス

-- スキーマ + パッケージ + メンバー
BEGIN
  hr.emp_pkg.get_salary(100);
END;
/

解決策⑤ パッケージ再コンパイル

ALTER PACKAGE my_pkg COMPILE;
ALTER PACKAGE my_pkg COMPILE BODY;

-- 一括
BEGIN
  UTL_RECOMP.recomp_parallel(4);
END;
/

解決策⑥ オーバーロード確認

SELECT overload, position, argument_name, data_type, in_out
FROM all_arguments
WHERE object_name = 'PROC'
ORDER BY overload, position;

Rails / Java / Python 対応

Rails ActiveRecord

エラーハンドリング:

begin
  ActiveRecord::Base.connection.execute("BEGIN my_pkg.proc_a; END;")
rescue ActiveRecord::StatementInvalid => e
  if e.message.include?("PLS-00302")
    Rails.logger.error "Component not found: #{e.message}"
    # スキーマプレフィックス試行 or DBA 依頼
  end
end

マイグレーションでシノニム作成:

class CreateSynonym < ActiveRecord::Migration[8.0]
  def up
    execute "CREATE SYNONYM my_pkg FOR hr.my_pkg"
  end
end

Rails 8 系の詳細は Rails 8 アップグレードガイドの記事も参照してください。

Java (JDBC)

try {
    stmt.execute("BEGIN my_pkg.proc_a; END;");
} catch (SQLException e) {
    if (e.getMessage().contains("PLS-00302")) {
        logger.error("Component not found: " + e.getMessage());
        // スキーマプレフィックス試行
        stmt.execute("BEGIN hr.my_pkg.proc_a; END;");
    }
}

Python (oracledb)

import oracledb

try:
    cursor.callproc("my_pkg.proc_a")
except oracledb.DatabaseError as e:
    error_obj, = e.args
    if "PLS-00302" in error_obj.message:
        # フルパス試行
        cursor.callproc("hr.my_pkg.proc_a")

実践シナリオ

シナリオ1:新規パッケージ開発

-- 1. SPEC 定義(外部公開メンバー)
CREATE OR REPLACE PACKAGE emp_pkg IS
  -- Public API
  PROCEDURE get_salary(p_id NUMBER);
  FUNCTION get_bonus(p_id NUMBER) RETURN NUMBER;
END emp_pkg;
/

-- 2. BODY 実装(private + public)
CREATE OR REPLACE PACKAGE BODY emp_pkg IS
  -- Private helper
  FUNCTION calc_tax(amt NUMBER) RETURN NUMBER IS
  BEGIN
    RETURN amt * 0.1;
  END;
  
  -- Public implementations
  PROCEDURE get_salary(p_id NUMBER) IS
    v_sal NUMBER;
  BEGIN
    -- 内部で private 使用: OK
    v_sal := 1000 - calc_tax(1000);
  END;
  
  FUNCTION get_bonus(p_id NUMBER) RETURN NUMBER IS
  BEGIN
    RETURN 500;
  END;
END emp_pkg;
/

-- 外部からの呼び出しテスト
BEGIN emp_pkg.get_salary(100); END;   -- OK
BEGIN emp_pkg.calc_tax(100); END;      -- PLS-00302

シナリオ2:スキーマ間の呼び出し設定

-- HR スキーマで
CREATE PACKAGE hr.emp_pkg IS
  PROCEDURE proc_a;
END;
/

GRANT EXECUTE ON hr.emp_pkg TO scott;

-- SCOTT スキーマで
CONNECT scott/tiger
CREATE SYNONYM emp_pkg FOR hr.emp_pkg;

BEGIN emp_pkg.proc_a; END;   -- OK

シナリオ3:INVALID オブジェクト対処

-- 1. INVALID 特定
SELECT owner, object_name, object_type
FROM dba_objects
WHERE status = 'INVALID';

-- 2. 個別再コンパイル
ALTER PACKAGE emp_pkg COMPILE;
ALTER PACKAGE emp_pkg COMPILE BODY;

-- 3. エラー確認
SELECT line, position, text 
FROM user_errors WHERE name = 'EMP_PKG';

-- 4. 一括再コンパイル
BEGIN
  UTL_RECOMP.recomp_parallel(4);
END;
/

シナリオ4:Crystal Reports 対応

Crystal Reports は SCHEMA.PROC 形式で強制
→ ユーザーが SCHEMA を所有していても PLS-00302 発生

対処:
1. Admin/SYS でリフレッシュ
2. PUBLIC SYNONYM 作成
3. Crystal Reports 側の設定変更

シナリオ5:DataGrip デバッグ対応

-- STUDENT ユーザーに debug 権限
GRANT DEBUG CONNECT SESSION TO student;
GRANT DEBUG ANY PROCEDURE TO student;

-- パッケージが INVALID でないか確認
SELECT status FROM user_objects WHERE object_name = 'MY_PKG';

シナリオ6:Docker Oracle テスト

docker exec -it oracle-xe sqlplus scott/tiger <<EOF
CREATE PACKAGE test_pkg AS
  PROCEDURE proc_a;
END;
/
CREATE PACKAGE BODY test_pkg AS
  FUNCTION private_helper RETURN NUMBER IS
  BEGIN
    RETURN 1;
  END;
  
  PROCEDURE proc_a IS
    v NUMBER;
  BEGIN
    v := private_helper;   -- OK
    DBMS_OUTPUT.PUT_LINE(v);
  END;
END;
/

-- 外部から
BEGIN test_pkg.proc_a; END;
/
-- OK

BEGIN test_pkg.private_helper; END;
/
-- PLS-00302
EOF

Docker 関連は docker daemon 接続エラーの記事、Docker no space left on device の記事も参照してください。

シナリオ7:Rails マイグレーション

class SetupOraclePackage < ActiveRecord::Migration[8.0]
  def up
    execute <<-SQL
      CREATE OR REPLACE PACKAGE app_pkg IS
        PROCEDURE process_order(p_id NUMBER);
      END;
    SQL
    
    execute <<-SQL
      CREATE OR REPLACE PACKAGE BODY app_pkg IS
        PROCEDURE process_order(p_id NUMBER) IS
        BEGIN
          UPDATE orders SET status = 'processed' WHERE id = p_id;
        END;
      END;
    SQL
  end
  
  def down
    execute "DROP PACKAGE app_pkg"
  end
end

Rails 8 系の詳細は Rails 8 アップグレードガイドの記事、rails db:migrate 使い方の記事も参照してください。

シナリオ8:Oracle EBS カスタム開発

-- APPS スキーマにカスタムパッケージ
CREATE OR REPLACE PACKAGE apps.xxcust_pkg IS
  PROCEDURE process_data;
END;
/

-- 業務ユーザーからアクセス
CREATE SYNONYM biz_user.xxcust_pkg FOR apps.xxcust_pkg;
GRANT EXECUTE ON apps.xxcust_pkg TO biz_user;

シナリオ9:Java Spring での対処

@Service
public class OracleService {
    @Autowired
    private JdbcTemplate jdbc;
    
    public void callPackage(String pkgName, String procName) {
        try {
            jdbc.execute("BEGIN " + pkgName + "." + procName + "; END;");
        } catch (DataAccessException e) {
            if (e.getMessage().contains("PLS-00302")) {
                logger.error("Component not found");
                // フルパスでリトライ
                jdbc.execute("BEGIN hr." + pkgName + "." + procName + "; END;");
            }
        }
    }
}

シナリオ10:Autonomous DB での対応

-- Autonomous DB でも同様
-- ADMIN でパッケージ作成 → 業務ユーザーへの
-- シノニム + GRANT EXECUTE 必須

トラブルシューティング

スペルは正しいのに PLS-00302

INVALID オブジェクトの可能性、再コンパイル。

GRANT EXECUTE でも解決しない

シノニム作成必須GRANT EXECUTE だけでは名前解決不能。

突然発生した PLS-00302

Oracle パッチ後の可能性、Admin/SYS でリフレッシュ。

DataGrip でのみ発生

IDE 特有の問題、SQL Developer で確認、DEBUG 権限追加。

Rails 呼び出しで発生

接続プールリセット、シノニム作成、フルパス使用。

PostgreSQL からの移行

PG は関数ベース、Oracle パッケージ構造の理解必要。


よくある質問(FAQ)

Q1. PLS-00302 と PLS-00201 の違い

  • 00302: コンポーネント(メンバー)が見えない(親は見えた)
  • 00201: 識別子全体が見えない

Q2. GRANT EXECUTE で十分か

不十分シノニム必須 or フルパス

Q3. private メンバーへのアクセス

不可、SPEC に宣言追加 or 内部経由。

Q4. INVALID の対処

ALTER PACKAGE … COMPILE で再コンパイル。

Q5. Rails での対応

シノニム作成 or フルパス使用

Q6. Java での対応

フルパス試行 + 例外処理。

Q7. Python での対応

oracledb で callproc、フルパス指定。

Q8. DataGrip / VSCode

DEBUG 権限追加、SQL Developer で代替検証。

Q9. Crystal Reports

PUBLIC SYNONYM or Admin リフレッシュ。

Q10. 大文字小文字

引用符付きで作成すると case-sensitive、リネーム推奨。

Q11. Oracle パッチ後の突然発生

Admin/SYS でリフレッシュ、MOS で類似ケース確認。

Q12. パフォーマンスへの影響

コンパイルエラー、実行時パフォーマンス影響なし。


参考リンク

Oracle 公式


まとめ

PLS-00302: component must be declared の要点を再整理します。

エラーの本質

SCHEMA.PACKAGE.MEMBER のドット表記で
親(SCHEMA/PACKAGE)は解決できたが
子(MEMBER/COMPONENT)が見つからない

エラーメッセージの読み方

PLS-00302: component 'X' must be declared
                      ↑
              メンバー名(コンポーネント)

= 親は見えたが X が見えない

姉妹エラー4種

エラー意味
PLS-00302コンポーネント(メンバー)未宣言
PLS-00201識別子全体が未宣言
PLS-00306引数の数/型が不一致
PLS-00323subprogram not declared

10大原因

#原因対処
スペルミス修正
BODY のみ定義SPEC 追加
private 外部アクセスpublic 化 or 経由
スキーマ違いシノニム作成
GRANT のみシノニム必須
大文字小文字リネーム
INVALID再コンパイル
Object Type メソッド追加
RECORD フィールド追加
オーバーロード引数確認

6つの解決策

-- ① スペル修正
BEGIN emp_pkg.get_salary(100); END;

-- ② SPEC 追加
CREATE OR REPLACE PACKAGE emp_pkg IS
  PROCEDURE get_salary(p_id NUMBER);
  FUNCTION helper_func RETURN NUMBER;   -- 追加
END;

-- ③ シノニム作成
CREATE SYNONYM emp_pkg FOR hr.emp_pkg;
CREATE PUBLIC SYNONYM emp_pkg FOR hr.emp_pkg;

-- ④ 明示プレフィックス
BEGIN hr.emp_pkg.get_salary(100); END;

-- ⑤ 再コンパイル
ALTER PACKAGE emp_pkg COMPILE;
UTL_RECOMP.recomp_parallel(4);

-- ⑥ オーバーロード確認
SELECT * FROM all_arguments WHERE object_name = 'PROC';

診断クエリ Top 3

-- ① パッケージ内メンバー
SELECT procedure_name, overload 
FROM all_procedures
WHERE owner = 'HR' AND object_name = 'EMP_PKG';

-- ② 引数
SELECT position, argument_name, data_type 
FROM all_arguments
WHERE package_name = 'EMP_PKG' 
  AND object_name = 'GET_SALARY';

-- ③ シノニム
SELECT * FROM all_synonyms 
WHERE synonym_name = 'EMP_PKG';

GRANT EXECUTE の落とし穴

-- ❌ これだけでは不十分
GRANT EXECUTE ON hr.emp_pkg TO scott;

-- ✅ シノニム必須
CREATE SYNONYM emp_pkg FOR hr.emp_pkg;

-- または PUBLIC
CREATE PUBLIC SYNONYM emp_pkg FOR hr.emp_pkg;

各言語での対応

Rails:  シノニム作成 or フルパス使用
Java:   例外処理 + フルパス試行
Python: oracledb callproc フルパス指定
共通:   スキーマ + パッケージ + メンバー明示

予防のポイント

1. 命名規則を統一(スペルミス回避)
2. IDE のオートコンプリート活用
3. SPEC vs BODY の区別明確化
4. private メンバーは内部使用のみ
5. スキーマ間参照は SYNONYM 必須
6. INVALID オブジェクトは即再コンパイル
7. 引用符付き識別子を避ける
8. Rails マイグレーションで SYNONYM 作成
9. Oracle EBS 等は Vendor 手順遵守
10. Autonomous DB でも同じルール

これらの知識は、Oracle での PL/SQL 開発・パッケージ設計・DBA 運用・Oracle EBS 管理・Rails / Java / Python アプリ運用・DataGrip / VSCode / Crystal Reports 等の各種ツール利用・スキーマ設計など、あらゆる場面で活用できます。本記事をブックマークしておけば、PLS-00302 に出会っても冷静に的確に対処できるようになります。


本記事は2026年6月時点の情報をもとに、Oracle Database 19c〜23ai での動作確認・公式ドキュメントに基づき作成しています。Oracle のバージョンにより挙動が異なる場合があるため、最新の情報は Oracle 公式ドキュメント(docs.oracle.com)もあわせてご確認ください。