【完全ガイド】ORA-04065: not executed, altered or dropped package の原因と解決方法|3兄弟完全比較・Shared Pool・EBR 徹底解説
- 作成日 2026.08.25
- Oracle Database
Oracle 開発者・DBA がパッケージ更新運用で頻繁に遭遇するエラー:
ORA-04068: existing state of packages has been discarded
ORA-04061: existing state of package "SCOTT.MY_PKG" has been invalidated
ORA-04065: not executed, altered or dropped package "SCOTT.MY_PKG"
ORA-06508: PL/SQL: could not find program unit being called
ORA-06512: at line 1
**「変更/削除されたため実行不可」**というシンプルなメッセージ。Oracle のパッケージ状態管理の3兄弟エラーの1つです:
ORA-04068(DISCARDED、破棄)ORA-04061(INVALIDATED、無効化)ORA-04065(altered/dropped、変更/削除で実行不可) ← 本記事ORA-06508(program unit not found、併発)
このエラーの本質は、Oracle がパッケージの変更/削除を検出:
1. セッション A がパッケージ P を実行中
2. 別セッション B(DBA / デプロイ)が P を変更/削除
3. セッション A が P を再度呼び出し
4. → Oracle が P の変更を検出
5. → ORA-04065 発生(呼び出し不可)
- 1. 結論:再実行 or Shared Pool フラッシュ
- 2. Oracle パッケージ変更の仕組み
- 3. 【原因①】パッケージ再コンパイル中(最頻出)
- 4. 【原因②】Oracle E-Business Suite Workflow
- 5. 【原因③】IFS ERP カスタム view
- 6. 【原因④】Oracle datapatch 中
- 7. 【原因⑤】Spring Boot Java Callable
- 8. 【原因⑥】Oracle Integration Cloud (OIC)
- 9. 【原因⑦】CI/CD デプロイ中
- 10. 【原因⑧】Rails マイグレーション
- 11. 【原因⑨】共通ライブラリパッケージ更新
- 12. 【原因⑩】TYPE / OBJECT 削除
- 13. 診断ツール完全リファレンス
- 14. 6つの解決策 完全リファレンス
- 15. Rails / Java / Python 対応
- 16. 実践シナリオ
- 17. トラブルシューティング
- 18. よくある質問(FAQ)
- 19. 参考リンク
- 20. まとめ
パッケージ状態エラー3兄弟の位置づけ
3つのエラーは通常セットで発生、それぞれの意味:
ORA-04068: 「状態が破棄された」(実行時、セッションレベル)
→ セッション A の P の状態がクリアされた
ORA-04061: 「状態が無効化された」(コンパイル時検出)
→ セッション A の状態と新しい P が不整合
ORA-04065: 「変更/削除されたため実行不可」(実行拒否)
→ Oracle が呼び出し自体を拒否
ORA-06508: 「プログラムユニット発見不可」
→ 実際の呼び出し失敗
現場で最も典型的なパターン:
- パッケージ本体 (
BODY) の再コンパイル中 - Oracle E-Business Suite Workflow(PO 承認 / Absence 承認等)
- IFS ERP のカスタム view / SSIS パッケージ
- Oracle Database Proactive Patch(datapatch)
- Spring Boot Java Callable Statement
- Oracle Integration Cloud (OIC) Database Adapter
- CI/CD デプロイパイプライン
- Rails マイグレーション中
- 共通ライブラリパッケージの更新
DROP TYPEによる依存パッケージ無効化
さらに、Oracle 公式ドキュメントが示す推奨対処:
Cause: Attempt to execute a stored procedure that has been altered
or dropped thus making it not callable from the calling procedure.
Action: Recompile its dependents.
多くの日本語記事が「再コンパイルせよ」で終わりますが、実務では:
- 3兄弟エラーの厳密な違いの理解
ALTER SYSTEM FLUSH SHARED_POOLの使い所とリスクDBMS_SHARED_POOL.PURGEによる特定カーソルのパージV$SQLから依存カーソルの特定Edition-Based Redefinition (EBR)による回避PRAGMA SERIALLY_REUSABLEの効果- Oracle EBS
adadminでの対処 - Rails ActiveRecord 接続プールのリセット
- Oracle 26ai
SESSION_EXIT_ON_PACKAGE_STATE_ERROR新機能 datapatch -verboseの再実行推奨
さらに、Oracle E-Business Suite (EBS) や IFS ERP などのエンタープライズアプリでは、特定のパターンが知られています:
IFS ERP カスタム view + SSIS:
ORA-04065 が occasionally 発生 → SSIS リトライで自己回復
Oracle EBS PO Workflow:
Notification Mailer 停止 → SHARED_POOL フラッシュ → 再起動
Oracle datapatch 12.1.0.2.190716:
再実行(rerun)で解消
本記事では、ORA-04065: not executed, altered or dropped の完全な原因と解決方法を、リファレンスとして実用的に整理します。3兄弟の完全比較、10大発生パターン、6つの解決策、Rails/Java/Python 対応、実践シナリオ、FAQまで完全網羅。この1本で ORA-04065 に冷静に対処できるようになります。
結論:再実行 or Shared Pool フラッシュ
時間がない方向けに、最速の対処を先に示します。
エラーメッセージの読み方
ORA-04065: not executed, altered or dropped package "SCHEMA.PACKAGE"
↑
変更/削除されたパッケージ
= 呼び出そうとしたパッケージが altered/dropped されている
最速の対処
即時対処: 再実行(同じ呼び出しをリトライ)
→ Oracle が自動的にパッケージ状態を再初期化
→ 通常成功
失敗する場合:
1. Shared Pool フラッシュ
2. 依存カーソルパージ
3. パッケージ再コンパイル
パッケージ状態エラー3兄弟
| エラー | 意味 | タイミング |
|---|---|---|
| ORA-04068 | 状態が DISCARDED(破棄) | 実行時 |
| ORA-04061 | 状態が INVALIDATED(無効化) | コンパイル時検出 |
| ORA-04065 | altered/dropped で実行不可 | 実行拒否 |
| ORA-06508 | プログラムユニット発見不可 | 併発 |
通常セットで発生、原因は同じ(パッケージ変更/削除)。
6つの解決策
| # | 手法 | 使う場面 |
|---|---|---|
| ① | 再実行 | 自動回復(多くの場合) |
| ② | Shared Pool フラッシュ | 緊急対応 |
| ③ | 依存カーソルパージ | 特定対処 |
| ④ | パッケージ再コンパイル | INVALID 対処 |
| ⑤ | Edition-Based Redefinition | 24時間運用 |
| ⑥ | SESSION_EXIT_ON_PACKAGE_STATE_ERROR (26ai) | 最新環境 |
詳細は以下で解説します。
Oracle パッケージ変更の仕組み
パッケージ変更のライフサイクル
1. パッケージ P 作成 → 全セッションで使用可能
2. セッション A が P を実行
→ セッションのパッケージ状態が確立
3. 別セッションで P を CREATE OR REPLACE
→ Shared Pool 内の P コピーが INVALID に
4. セッション A が P を再度呼び出し
→ 3兄弟エラー発生
5. セッション A が同じ呼び出しをリトライ
→ 状態が再初期化されて成功(多くの場合)
3 兄弟の発生順序
実際のエラー出力:
ORA-04068: existing state of packages has been discarded ← 最初
ORA-04061: existing state of package ... invalidated ← カスケード
ORA-04065: not executed, altered or dropped ← 実行拒否
ORA-06508: PL/SQL: could not find program unit being called ← 実行失敗
ORA-06512: at line 1 ← 位置
読み方:
- 04068: セッション状態が破棄された
- 04061: 検出された不整合
- 04065: そのため実行できない
- 06508: プログラムユニットが見つからない
自動回復の仕組み
Oracle は次回呼び出しで自動的に状態再初期化:
BEGIN my_pkg.proc_a; END; -- 1 回目: ORA-04065
BEGIN my_pkg.proc_a; END; -- 2 回目: 通常成功
多くのアプリで自動リトライで解決。
【原因①】パッケージ再コンパイル中(最頻出)
シナリオ
セッション A: my_pkg 実行中
セッション B (DBA):
CREATE OR REPLACE PACKAGE my_pkg AS ... END;
セッション A: my_pkg 再度呼び出し
→ ORA-04065
診断
-- パッケージの最終更新時刻
SELECT owner, object_name, object_type, status, last_ddl_time
FROM dba_objects
WHERE object_name = 'MY_PKG'
ORDER BY last_ddl_time DESC;
対処
A. 再実行:
BEGIN
my_pkg.proc_a; -- 初回: ORA-04065
END;
/
BEGIN
my_pkg.proc_a; -- 2 回目: 通常成功
END;
/
B. アプリで自動リトライ:
def call_proc
ActiveRecord::Base.connection.execute("BEGIN my_pkg.proc_a; END;")
rescue ActiveRecord::StatementInvalid => e
if e.message.include?("ORA-04065") && (retries ||= 0) < 3
retries += 1
retry
end
raise
end
パッケージ状態関連は ORA-04068: existing state of packages の記事、ORA-04061: existing state has been invalidated の記事も参照してください。
【原因②】Oracle E-Business Suite Workflow
症状(現場頻発)
ORA-04068: existing state of packages has been discarded
ORA-04061: existing state of package body "APPS.PO_REQAPPROVAL_INIT1"
has been invalidated
ORA-04065: not executed, altered or dropped package body
"APPS.PO_REQAPPROVAL_INIT1"
ORA-06508: PL/SQL: could not find program unit being called
PO Requisition Approval, Workflow Notification 失敗。
対処(Oracle 公式手順)
STEP 1: Shared Pool フラッシュ:
SQL> CONN / AS SYSDBA
SQL> ALTER SYSTEM FLUSH SHARED_POOL;
STEP 2: Concurrent Manager 停止 → adadmin で再コンパイル:
$COMMON_TOP/admin/scripts/$SID/adstpall.sh apps/apps
adadmin
# Recompile APPS Schema オプション
$COMMON_TOP/admin/scripts/$SID/adstrtal.sh apps/apps
STEP 3: 定期的な INVALID 再コンパイル:
BEGIN
UTL_RECOMP.recomp_parallel(4, 'APPS');
END;
/
【原因③】IFS ERP カスタム view
シナリオ(実例)
IFS ERP カスタム view + SSIS パッケージ:
「Most of the time works, occasionally errors with 4068/4061/4065」
ORA-04068: existing state of packages has been discarded
ORA-04061: existing state of package "IFSAPP.SHIPMENT_CFP"
has been invalidated
ORA-04065: not executed, altered or dropped package "IFSAPP.SHIPMENT_CFP"
対処
A. SSIS リトライロジック:
try {
ExecuteSSISPackage();
} catch (SqlException ex) {
if (ex.Number == 4065 || ex.Number == 4068) {
Thread.Sleep(1000);
ExecuteSSISPackage(); // リトライ
}
}
B. IFS パッケージ再コンパイル(メンテナンス時)。
【原因④】Oracle datapatch 中
症状(12.1.0.2.190716 パッチ適用中)
Patch 29496791 apply (pdb PDB$SEED): WITH ERRORS
Error at line 26523: ORA-04068: existing state of packages has been discarded
Error at line 26524: ORA-04061: existing state of package body
"SYS.DBMS_REGISTRY_SYS" has been invalidated
Error at line 26526: ORA-04065: not executed, altered or dropped package body
Error at line 26528: ORA-06508: PL/SQL: could not find program unit being called
内部スクリプト実行順序の問題。
対処(Oracle 公式推奨)
A. datapatch を再実行:
$ORACLE_HOME/OPatch/datapatch -verbose
# 2 回目実行で解消
B. 事前対処(datapatch 前):
-- 隠しパラメータ設定(一部の問題)
ALTER SYSTEM SET "_srvntfn_job_deq_timeout" = 0 SCOPE=SPFILE;
SHUTDOWN IMMEDIATE
STARTUP
【原因⑤】Spring Boot Java Callable
症状
Caused by: org.springframework.jdbc.UncategorizedSQLException:
CallableStatementCallback; uncategorized SQLException for SQL
[{call TEST1_PKG.matchUpdatedInventory(?, ?, ?, ?, ?)}];
SQL state [72000]; ERROR code [4068];
ORA-04068: existing state of packages has been discarded
ORA-04061: existing state of package "TEST1.TEST1_PKG" has been invalidated
ORA-04065: not executed, altered or dropped package "TEST1.TEST1_PKG"
対処
A. Spring での自動リトライ:
@Retryable(
value = SQLException.class,
maxAttempts = 3,
backoff = @Backoff(delay = 1000)
)
public void callInventoryUpdate() {
jdbcTemplate.execute("{call TEST1_PKG.matchUpdatedInventory(?, ?, ?, ?, ?)}");
}
B. 接続プールリセット:
if (e.getErrorCode() == 4065 || e.getErrorCode() == 4068) {
dataSource.evictConnections();
}
【原因⑥】Oracle Integration Cloud (OIC)
症状
Oracle 公式が troubleshooting ページで明示:
Resolve Error ORA-04068: existing state of packages has been discarded
Database Adapter 経由でストアド呼び出し。
対処
A. OIC 側リトライ設定。 B. ストアド設計見直し(グローバル状態除去)。
【原因⑦】CI/CD デプロイ中
シナリオ
- name: Deploy PL/SQL
run: |
sqlplus $DB_USER/$DB_PW <<EOF
@deploy_packages.sql
EOF
# アプリ継続稼働中 → ORA-04065 頻発
解決
A. デプロイ順序(推奨):
# 1. アプリ一時停止
kamal app stop
# 2. パッケージデプロイ
sqlplus $DB_USER/$DB_PW @deploy_packages.sql
# 3. アプリ再起動
kamal app start
B. アプリでリトライ。
Kamal 2 デプロイの詳細は Kamal 2 デプロイの記事、rails db:migrate 使い方の記事も参照してください。
【原因⑧】Rails マイグレーション
シナリオ
class UpdatePackages < ActiveRecord::Migration[8.0]
def up
execute "CREATE OR REPLACE PACKAGE my_pkg AS ... END;"
end
end
# Web アプリが my_pkg 使用中
# → ORA-04065
解決
class UpdatePackages < ActiveRecord::Migration[8.0]
def up
execute "CREATE OR REPLACE PACKAGE my_pkg AS ... END;"
execute "CREATE OR REPLACE PACKAGE BODY my_pkg AS ... END;"
# 接続プールリセット
ActiveRecord::Base.connection_pool.disconnect!
end
end
Rails 8 系の詳細は Rails 8 アップグレードガイドの記事も参照してください。
【原因⑨】共通ライブラリパッケージ更新
シナリオ
-- 共通ライブラリ COMMON_UTIL 更新
CREATE OR REPLACE PACKAGE common_util AS
FUNCTION format_date(d DATE) RETURN VARCHAR2;
END;
/
-- 依存する多数のパッケージが INVALID に
-- 業務中に大量 ORA-04065 発生
解決
A. 依存関係一括再コンパイル:
BEGIN
UTL_RECOMP.recomp_parallel(4);
END;
/
B. デプロイ時にアプリ停止(推奨)。
【原因⑩】TYPE / OBJECT 削除
シナリオ
-- TYPE 定義
CREATE TYPE addr_t AS OBJECT (...);
-- 依存パッケージ
CREATE PACKAGE addr_pkg AS
PROCEDURE proc(a addr_t);
END;
/
-- TYPE 削除
DROP TYPE addr_t;
-- addr_pkg 呼び出し → ORA-04065
解決
A. TYPE 再作成 + パッケージ再コンパイル:
CREATE OR REPLACE TYPE addr_t AS OBJECT (...);
ALTER PACKAGE addr_pkg COMPILE;
B. 事前依存関係確認:
SELECT * FROM user_dependencies
WHERE referenced_name = 'ADDR_T';
診断ツール完全リファレンス
エラーコード確認
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE = -4065 THEN
DBMS_OUTPUT.PUT_LINE('Package altered/dropped');
ELSIF SQLCODE = -4061 THEN
DBMS_OUTPUT.PUT_LINE('Package state invalidated');
ELSIF SQLCODE = -4068 THEN
DBMS_OUTPUT.PUT_LINE('Package state discarded');
END IF;
END;
V$SQL で依存カーソル
SELECT sql_id, hash_value, address, sql_text
FROM v$sql
WHERE sql_text LIKE '%MY_PKG%'
OR sql_fulltext LIKE '%MY_PKG%';
INVALID オブジェクト
SELECT owner, object_name, object_type, last_ddl_time
FROM dba_objects
WHERE status = 'INVALID'
ORDER BY last_ddl_time DESC;
V$SESSION
SELECT sid, serial#, username, module, status
FROM v$session
WHERE prev_sql_id IN (
SELECT sql_id FROM v$sql WHERE sql_text LIKE '%MY_PKG%'
);
DBA_DDL_LOG
-- パッケージ変更履歴
SELECT * FROM dba_ddl_log
WHERE object_name = 'MY_PKG'
ORDER BY occurred DESC;
6つの解決策 完全リファレンス
解決策① 再実行(自動回復)
-- Oracle は次回呼び出しで自動的に状態再初期化
BEGIN my_pkg.proc_a; END; -- 1 回目: ORA-04065
BEGIN my_pkg.proc_a; END; -- 2 回目: 通常成功
多くの場合これで解決。
解決策② Shared Pool フラッシュ
-- 全 Shared Pool クリア(緊急対応、パフォーマンス影響大)
SQL> CONN / AS SYSDBA
SQL> ALTER SYSTEM FLUSH SHARED_POOL;
-- Result Cache もクリア
SQL> ALTER SYSTEM FLUSH BUFFER_CACHE;
-- ⚠️ 業務中は慎重に
解決策③ 依存カーソルパージ
-- 特定 SQL のカーソルパージ(12c+)
DECLARE
v_addr VARCHAR2(50);
v_hash NUMBER;
BEGIN
FOR r IN (
SELECT address, hash_value
FROM v$sql
WHERE sql_text LIKE '%MY_PKG%'
) LOOP
DBMS_SHARED_POOL.PURGE(
r.address || ',' || r.hash_value,
'C'
);
END LOOP;
END;
/
Shared Pool 全体フラッシュより影響小。
解決策④ パッケージ再コンパイル
-- 個別
ALTER PACKAGE my_pkg COMPILE;
ALTER PACKAGE my_pkg COMPILE BODY;
-- スキーマ一括
BEGIN
DBMS_UTILITY.COMPILE_SCHEMA('APP_USER');
END;
/
-- 並列(推奨)
BEGIN
UTL_RECOMP.recomp_parallel(4, 'APP_USER');
END;
/
INVALID 関連は PLS-00905: object is invalid の記事も参照してください。
解決策⑤ Edition-Based Redefinition (EBR)
Oracle 11g R2+ の高度な機能、無停止デプロイ:
-- 新エディション作成
CREATE EDITION new_edition;
-- 新エディションでパッケージ変更
ALTER SESSION SET EDITION = new_edition;
CREATE OR REPLACE PACKAGE my_pkg AS ... END;
-- 既存セッションは旧エディションで動作継続
-- 新セッションのみ新エディション
-- → ORA-04065 回避
-- 全セッション移行後
ALTER DATABASE DEFAULT EDITION = new_edition;
解決策⑥ SESSION_EXIT_ON_PACKAGE_STATE_ERROR (26ai)
Oracle 26ai 新機能:
ALTER SYSTEM SET session_exit_on_package_state_error = TRUE;
効果:
- ORA-04065/04068 発生時、セッション自動切断
- アプリの接続再取得ロジックで自動回復
- silent data corruption 防止
Rails / Java / Python 対応
Rails ActiveRecord
自動リトライ + 接続リセット:
module OraclePackageRetry
def call_with_retry(sql, max_retries: 3)
retries = 0
begin
ActiveRecord::Base.connection.execute(sql)
rescue ActiveRecord::StatementInvalid => e
if package_state_error?(e) && retries < max_retries
retries += 1
Rails.logger.warn "Package state error, retry #{retries}"
ActiveRecord::Base.connection.reconnect!
retry
end
raise
end
end
private
def package_state_error?(e)
e.message.include?("ORA-04065") ||
e.message.include?("ORA-04068") ||
e.message.include?("ORA-04061")
end
end
Rails 8 系の詳細は Rails 8 アップグレードガイドの記事も参照してください。
Java (JDBC / Spring)
Spring Retry:
@Service
public class PackageCaller {
@Retryable(
value = SQLException.class,
maxAttempts = 3,
backoff = @Backoff(delay = 1000, multiplier = 2)
)
public void callWithRetry(String sql) {
try (Connection conn = ds.getConnection();
Statement stmt = conn.createStatement()) {
stmt.execute(sql);
} catch (SQLException e) {
if (isPackageStateError(e)) {
throw e; // リトライ対象
}
throw new RuntimeException(e);
}
}
private boolean isPackageStateError(SQLException e) {
int code = e.getErrorCode();
return code == 4065 || code == 4068 || code == 4061;
}
}
Python (oracledb)
import oracledb
import time
def call_with_retry(dsn, user, pw, sql, max_retries=3):
package_state_errors = {4065, 4068, 4061}
for attempt in range(max_retries):
try:
with oracledb.connect(user=user, password=pw, dsn=dsn) as conn:
cursor = conn.cursor()
cursor.execute(sql)
return
except oracledb.DatabaseError as e:
error_obj, = e.args
if error_obj.code in package_state_errors and attempt < max_retries - 1:
print(f"Package state error, retry {attempt + 1}")
time.sleep(2 ** attempt)
continue
raise
実践シナリオ
シナリオ1:本番緊急対応
-- 1. 発生確認
SELECT sid, serial#, username, program, status
FROM v$session
WHERE status = 'ACTIVE';
-- 2. Shared Pool フラッシュ
SQL> CONN / AS SYSDBA
SQL> ALTER SYSTEM FLUSH SHARED_POOL;
-- 3. パッケージ再コンパイル
ALTER PACKAGE app.my_pkg COMPILE BODY;
-- 4. INVALID 一括修復
BEGIN
UTL_RECOMP.recomp_parallel(4, 'APP');
END;
/
-- 5. アプリ側リトライで自動回復確認
シナリオ2:Oracle EBS Workflow 対応
-- 1. 影響オブジェクト特定
SELECT owner, object_name, status
FROM dba_objects
WHERE status = 'INVALID' AND owner = 'APPS';
-- 2. Concurrent Manager 停止
-- $ $COMMON_TOP/admin/scripts/$SID/adstpall.sh apps/apps
-- 3. Shared Pool フラッシュ
SQL> CONN / AS SYSDBA
SQL> ALTER SYSTEM FLUSH SHARED_POOL;
-- 4. APPS 再コンパイル
BEGIN
UTL_RECOMP.recomp_parallel(4, 'APPS');
END;
/
-- 5. Notification Mailer 再起動
シナリオ3:Spring Boot での耐障害設計
@Configuration
@EnableRetry
public class RetryConfig {
@Bean
public RetryTemplate retryTemplate() {
RetryTemplate template = new RetryTemplate();
FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy();
backOffPolicy.setBackOffPeriod(1000);
template.setBackOffPolicy(backOffPolicy);
SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
retryPolicy.setMaxAttempts(3);
template.setRetryPolicy(retryPolicy);
return template;
}
}
@Service
public class PackageService {
@Autowired
private RetryTemplate retryTemplate;
public void callPackage() {
retryTemplate.execute(context -> {
jdbcTemplate.execute("{call my_pkg.proc_a}");
return null;
});
}
}
シナリオ4:Rails 接続プール管理
# config/initializers/oracle_retry.rb
class OracleRetryMiddleware
def initialize(app)
@app = app
end
def call(env)
@app.call(env)
rescue ActiveRecord::StatementInvalid => e
if package_state_error?(e)
# 接続プール全リセット
ActiveRecord::Base.connection_pool.disconnect!
# リトライ
@app.call(env)
else
raise
end
end
private
def package_state_error?(e)
[4065, 4068, 4061].any? { |code| e.message.include?("ORA-#{code.to_s.rjust(5, '0')}") }
end
end
シナリオ5:Oracle datapatch 対処
# 1. パッチ適用試行
$ORACLE_HOME/OPatch/datapatch -verbose
# 2. エラー確認(4068/4061/4065 出た場合)
tail -100 /u01/app/oracle/cfgtoollogs/sqlpatch/*.log
# 3. datapatch 再実行(Oracle 公式推奨)
$ORACLE_HOME/OPatch/datapatch -verbose
# 4. 通常 2 回目で成功
シナリオ6:CI/CD パイプライン統合
- name: Deploy PL/SQL (safe)
run: |
# 1. アプリ停止
kubectl scale deployment app --replicas=0
sleep 30 # 接続クローズ待機
# 2. パッケージデプロイ
sqlplus $DB_USER/$DB_PW <<EOF
@deploy_packages.sql
EOF
# 3. INVALID 確認 & 修復
sqlplus / as sysdba <<EOF
BEGIN
UTL_RECOMP.recomp_parallel(4);
END;
/
SELECT COUNT(*) FROM dba_objects WHERE status = 'INVALID';
EOF
# 4. アプリ再起動
kubectl scale deployment app --replicas=3
Kamal 2 デプロイの詳細は Kamal 2 デプロイの記事を参照してください。
シナリオ7:Docker Oracle でのテスト
docker exec -it oracle-xe sqlplus scott/tiger <<EOF
CREATE OR REPLACE PACKAGE test_pkg AS
PROCEDURE proc_a;
END;
/
CREATE OR REPLACE PACKAGE BODY test_pkg AS
PROCEDURE proc_a IS
BEGIN
DBMS_OUTPUT.PUT_LINE('OK');
END;
END;
/
BEGIN test_pkg.proc_a; END;
/
-- OK
-- 別セッションで再作成
-- CREATE OR REPLACE PACKAGE test_pkg AS ... END;
BEGIN test_pkg.proc_a; END;
/
-- ORA-04068 + 04061 + 04065
BEGIN test_pkg.proc_a; END;
/
-- 再実行で成功
EOF
Docker 関連は docker daemon 接続エラーの記事、Docker no space left on device の記事も参照してください。
シナリオ8:定期監視スクリプト
#!/bin/bash
# monitor_package_state.sh
# INVALID オブジェクト監視
invalid=$(sqlplus -s / as sysdba <<EOF
SET HEADING OFF FEEDBACK OFF
SELECT COUNT(*) FROM dba_objects WHERE status = 'INVALID';
EXIT;
EOF
)
if [ "$invalid" -gt "0" ]; then
# 自動再コンパイル
sqlplus / as sysdba <<EOF
BEGIN
UTL_RECOMP.recomp_parallel(4);
END;
/
EOF
fi
crontab の詳細は crontab 使い方の記事も参照してください。
シナリオ9:Python での実装
import oracledb
import logging
from functools import wraps
logger = logging.getLogger(__name__)
def retry_on_package_error(max_retries=3):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
for attempt in range(max_retries):
try:
return func(*args, **kwargs)
except oracledb.DatabaseError as e:
error_obj, = e.args
if error_obj.code in (4065, 4068, 4061):
logger.warning(f"Package state error, retry {attempt + 1}")
continue
raise
raise Exception("Max retries exceeded")
return wrapper
return decorator
@retry_on_package_error(max_retries=3)
def call_stored_proc(cursor, proc_name):
cursor.callproc(proc_name)
シナリオ10:Autonomous DB での対応
-- Autonomous DB でも同じ動作
-- 26ai 環境では新機能活用推奨
ALTER SYSTEM SET session_exit_on_package_state_error = TRUE;
-- パッケージ状態エラー時にセッション自動切断
トラブルシューティング
再実行しても直らない
Shared Pool フラッシュ or 依存カーソルパージ:
ALTER SYSTEM FLUSH SHARED_POOL;
頻発する場合
根本原因: グローバル状態を持つパッケージ、または業務中のデプロイ。設計見直し。
Shared Pool フラッシュの影響
キャッシュクリアでパフォーマンス低下、業務時間外推奨。
特定カーソルだけパージしたい
BEGIN
DBMS_SHARED_POOL.PURGE('<address>,<hash>', 'C');
END;
/
EBR の導入コスト
設計変更大、慎重に計画。24時間運用では効果大。
PostgreSQL からの移行
PG は関数ベースでこの問題なし。移行時は状態管理見直し。
よくある質問(FAQ)
Q1. ORA-04065 と ORA-04061 の違い
- 04065: altered/dropped で実行不可
- 04061: 状態が invalidated
Q2. ORA-04068 との違い
- 04068: 状態が discarded(実行時)
- 04065: altered/dropped(実行拒否)
Q3. なぜ 3 兄弟でセット発生
パッケージ変更1 つのイベントが3 種類のエラーとして表現される。
Q4. 再実行で解決するか
多くの場合 YES。Oracle が自動再初期化。
Q5. Shared Pool フラッシュのリスク
全キャッシュクリア、パフォーマンス影響大。
Q6. Rails での対応
リトライ + 接続プールリセット。
Q7. Java での対応
Spring Retry or 手動リトライ。
Q8. Oracle EBS での対処
Notification Mailer 停止 + Shared Pool フラッシュ + 再コンパイル。
Q9. Oracle datapatch エラー
datapatch を再実行(Oracle 公式推奨)。
Q10. EBR の推奨環境
24時間運用、無停止デプロイ必須。
Q11. Oracle 26ai 新機能
SESSION_EXIT_ON_PACKAGE_STATE_ERROR で自動切断。
Q12. 予防策
- グローバル状態最小化
- デプロイ順序管理
- リトライロジック実装
- EBR 検討
参考リンク
Oracle 公式
- Oracle Database Error Messages: ORA-04065
- Oracle Database Error Messages: ORA-04068
- Oracle Database Development Guide: Edition-Based Redefinition
- DBMS_SHARED_POOL Package
まとめ
ORA-04065: not executed, altered or dropped package の要点を再整理します。
エラーの本質
呼び出そうとしたパッケージが altered/dropped されている
→ Oracle が呼び出しを拒否
→ 通常 ORA-04068 + ORA-04061 とセットで発生
→ ORA-06508 も併発
エラーメッセージの読み方
ORA-04065: not executed, altered or dropped package "SCHEMA.PACKAGE"
↑
変更/削除されたパッケージ
パッケージ状態エラー3兄弟
| エラー | 意味 | タイミング |
|---|---|---|
| ORA-04068 | DISCARDED(破棄) | 実行時 |
| ORA-04061 | INVALIDATED(無効化) | コンパイル時検出 |
| ORA-04065 | altered/dropped | 実行拒否 |
| ORA-06508 | プログラムユニット発見不可 | 併発 |
10大原因
| # | 原因 | 対処 |
|---|---|---|
| ① | パッケージ再コンパイル中 | 再実行 |
| ② | Oracle EBS Workflow | adadmin |
| ③ | IFS ERP + SSIS | リトライ |
| ④ | Oracle datapatch | 再実行 |
| ⑤ | Spring Boot Java | Spring Retry |
| ⑥ | OIC Database Adapter | リトライ設定 |
| ⑦ | CI/CD デプロイ | アプリ停止 |
| ⑧ | Rails migration | 接続プールリセット |
| ⑨ | 共通ライブラリ更新 | 一括再コンパイル |
| ⑩ | TYPE / OBJECT 削除 | 再作成 + COMPILE |
6つの解決策
-- ① 再実行(Oracle 自動回復)
BEGIN my_pkg.proc_a; END;
-- ② Shared Pool フラッシュ(緊急)
ALTER SYSTEM FLUSH SHARED_POOL;
-- ③ 依存カーソルパージ
DBMS_SHARED_POOL.PURGE('<addr>,<hash>', 'C');
-- ④ パッケージ再コンパイル
ALTER PACKAGE my_pkg COMPILE;
UTL_RECOMP.recomp_parallel(4);
-- ⑤ Edition-Based Redefinition
CREATE EDITION new_edition;
ALTER SESSION SET EDITION = new_edition;
-- ⑥ 26ai 新機能
ALTER SYSTEM SET session_exit_on_package_state_error = TRUE;
各言語での対応
Rails: リトライ + connection_pool.disconnect!
Java: Spring Retry + errorCode 判定
Python: DatabaseError.code チェック + リトライ
共通: 接続再取得ロジック実装
予防のポイント
1. グローバル状態を最小化
2. PRAGMA SERIALLY_REUSABLE 活用
3. リトライロジック実装
4. デプロイ順序管理(アプリ停止)
5. Rails 接続プールリセット
6. EBR 検討(24時間運用)
7. 26ai の新機能活用
8. 定期的な INVALID オブジェクト監視
9. Oracle EBS は Vendor 手順遵守
10. Oracle datapatch は 2 回実行前提
これらの知識は、Oracle での PL/SQL 開発・パッケージ設計・DBA 運用・Oracle EBS 管理・IFS ERP 運用・Rails / Java / Python アプリ運用・CI/CD パイプライン・24時間運用・データベースアップグレードなど、あらゆる場面で活用できます。本記事をブックマークしておけば、ORA-04065 に出会っても冷静に的確に対処できるようになります。
本記事は2026年6月時点の情報をもとに、Oracle Database 19c〜26ai での動作確認・公式ドキュメントに基づき作成しています。Oracle のバージョンにより挙動が異なる場合があるため、最新の情報は Oracle 公式ドキュメント(docs.oracle.com)もあわせてご確認ください。
-
前の記事
【完全ガイド】ORA-04061: existing state of … has been invalidated の原因と解決方法|ORA-04068 との違い・グローバル状態・EBR 徹底解説 2026.08.24
-
次の記事
【完全ガイド】PLS-00302: component must be declared の原因と解決方法|PLS-00201 との違い・シノニム・SPEC 未宣言 徹底解説 2026.08.25
コメントを書く