ORA-00604: error occurred at recursive SQL level 1 は、Oracleが内部的に実行する再帰SQLの処理中に別のエラーが発生したことを示すメッセージです。ログオン時、DDL実行時、トリガー実行時、データディクショナリ参照時などに出ることがあります。
重要なのは、ORA-00604 だけを見ても原因を特定できない点です。Oracle公式の説明でも、後続のエラーを確認して根本原因を直すことが案内されています。この記事では、後続エラーの読み方、ログオン/DDLトリガー、権限不足、無効オブジェクト、NLSや環境差分の切り分けを整理します。名前が似ている ORA-00600 は内部エラーであり、ORA-00604とは調査の入口が違います。
- ORA-00604が何を示しているか
- 直後に出るORAエラーを読む手順
- ログオントリガー、DDLトリガー、システムトリガーの確認SQL
- ORA-04088、ORA-06512、ORA-01031などが併発する場合の見方
- 一時回避と恒久対応の考え方
この記事で扱う範囲
この記事では、ORA-00604 が出た時にエラースタックを読み、ログオン/DDLトリガー、権限不足、無効オブジェクト、PL/SQL行番号を順に確認する流れを扱います。トリガーそのものの作り方や種類は別記事に任せ、ここでは障害調査で必要な確認SQLと判断ポイントに絞ります。
最初に結論:ORA-00604の次の行が本当の原因
ORA-00604は、単独の原因名ではなく「再帰SQL中に何かが失敗した」という入口です。本当に直すべき対象は、エラースタックの次の行以降に出る ORA-04088、ORA-01031、ORA-06512、ORA-06502 などです。
PL/SQLの行番号付きエラーは ORA-06512の原因と読み方、権限不足は ORA-01031完全ガイド、数値や文字列変換のPL/SQLエラーは ORA-06502の原因と解決方法 も参考にしてください。
エラーメッセージの読み方
典型的には、ORA-00604の後に別のORAエラーが続きます。次の例では、ログオントリガー実行中にトリガー内でエラーが起きています。
ORA-00604: error occurred at recursive SQL level 1 ORA-04088: error during execution of trigger 'SYS.LOGON_AUDIT_TRG' ORA-06512: at line 8
この場合、調査対象はORA-00604そのものではなく、SYS.LOGON_AUDIT_TRG というトリガーと、その8行目です。トリガー実行時エラーの考え方は PL/SQLトリガー完全ガイド と関連します。
よくある発生パターン
確認SQL
ログオン/DDLトリガーを確認する
まず、DATABASEまたはSCHEMAに作成されたシステムトリガーを確認します。Oracleのシステムトリガーは、ログオン、DDL、SERVERERRORなどのイベントで自動実行されます。
SELECT owner,
trigger_name,
trigger_type,
triggering_event,
table_owner,
status
FROM dba_triggers
WHERE triggering_event LIKE '%LOGON%'
OR triggering_event LIKE '%CREATE%'
OR triggering_event LIKE '%ALTER%'
OR triggering_event LIKE '%DROP%'
OR triggering_event LIKE '%SERVERERROR%'
ORDER BY owner, trigger_name;
DBA_TRIGGERS が参照できない場合は、権限のあるユーザーで確認するか、ALL_TRIGGERS / USER_TRIGGERS を使います。
トリガー本文を確認する
エラーにトリガー名が出ている場合は、該当トリガーの本文を確認します。参照している表、プロシージャ、パッケージ、権限が原因になっていることがあります。
SELECT owner,
name,
type,
line,
text
FROM dba_source
WHERE owner = 'SYS'
AND name = 'LOGON_AUDIT_TRG'
ORDER BY line;
コンパイルエラーを確認する
無効なトリガーや依存オブジェクトがある場合、実行時にORA-00604の後続エラーとして現れることがあります。コンパイルエラーは DBA_ERRORS で確認します。
SELECT owner,
name,
type,
line,
position,
text
FROM dba_errors
WHERE owner = 'SYS'
AND name = 'LOGON_AUDIT_TRG'
ORDER BY sequence;
無効オブジェクトを確認する
トリガーが呼び出すプロシージャやパッケージがINVALIDになっている場合もあります。関連スキーマの無効オブジェクトを確認します。
SELECT owner,
object_name,
object_type,
status
FROM dba_objects
WHERE status = 'INVALID'
AND owner IN ('SYS', 'APP')
ORDER BY owner, object_type, object_name;
後続エラー別の見方
ORA-04088が続く場合
ORA-04088 は、トリガー実行中にランタイムエラーが発生したことを示します。エラーに出ているトリガー名を確認し、トリガー内SQL、呼び出し先プロシージャ、例外処理を見直します。
ORA-00604: error occurred at recursive SQL level 1 ORA-04088: error during execution of trigger 'APP.DDL_AUDIT_TRG' ORA-06512: at line 15
ORA-01031が続く場合
ORA-01031 が続く場合、トリガー内で実行しているSQLに必要な権限が不足している可能性があります。PL/SQL内ではロール経由の権限が効かない場面があるため、直接付与された権限を確認します。
SELECT grantee,
owner,
table_name,
privilege
FROM dba_tab_privs
WHERE grantee = 'APP'
AND owner = 'SYS'
ORDER BY table_name, privilege;
権限不足の切り分けは ORA-01031完全ガイド を確認してください。
ORA-06512が続く場合
ORA-06512 はPL/SQLのエラー発生行を示します。ORA-00604と一緒に出る場合も、ORA-06512の行番号からトリガーやプロシージャのどこで失敗したかを追います。
行番号の読み方は ORA-06512の原因と読み方 に詳しくまとめています。
ログオンできない場合の一時回避
ログオントリガーが失敗して一般ユーザーが接続できない場合は、DBA権限を持つユーザーで接続し、原因トリガーを確認します。一般ユーザーだけが失敗するのか、特定スキーマだけが失敗するのか、DBAユーザーでは接続できるのかを分けると、トリガーの範囲を絞り込みやすくなります。本番では、無効化する前に影響範囲、監査要件、復旧手順を確認します。
- DBAまたは管理用ユーザーで接続できるか確認する
- 別ユーザーでは発生しないか確認する
- エラーに出ているトリガー名を控える
- 無効化する場合は、再有効化コマンドと戻し担当を決める
- 監査・セキュリティ要件に影響しないか確認する
-- 原因が明確で、緊急回避が必要な場合の例 ALTER TRIGGER sys.logon_audit_trg DISABLE; -- 修正後に再有効化 ALTER TRIGGER sys.logon_audit_trg ENABLE;
トリガー無効化は強い操作です。監査、セキュリティ、運用ルールに関係する場合があるため、原因調査と復旧計画をセットで行います。
やってはいけない対応
内部エラーとの違いは ORA-00600完全ガイド も参考になります。
本番対応チェックリスト
- ORA-00604の後続エラーをすべて控えた
- ログオン時、DDL時、特定SQL実行時のどれで出るか確認した
- エラーに出ているトリガー名と行番号を確認した
- DBA_TRIGGERSでLOGON/DDL/SERVERERRORトリガーを確認した
- DBA_SOURCEでトリガー本文を確認した
- DBA_ERRORSとDBA_OBJECTSで無効オブジェクトを確認した
- ORA-01031がある場合は直接権限を確認した
- トリガー無効化が必要な場合は影響範囲と戻し手順を決めた
再発防止
ORA-00604の再発防止では、ログオン/DDLトリガーを複雑にしすぎないことが重要です。トリガー内で外部状態に依存する処理、失敗しやすい監査テーブルINSERT、権限が曖昧なSQL、例外を握りつぶす処理は、障害時に原因を追いにくくします。
CREATE OR REPLACE TRIGGER app.logon_audit_trg
AFTER LOGON ON DATABASE
BEGIN
-- 失敗してもログオン全体を壊さない設計にするか、
-- 壊してよい要件なのかを事前に決める
INSERT INTO app.logon_audit(user_name, logon_time)
VALUES (SYS_CONTEXT('USERENV', 'SESSION_USER'), SYSDATE);
EXCEPTION
WHEN OTHERS THEN
-- 本番要件に応じて、記録だけして再送出しない/再送出するを決める
NULL;
END;
/
例外をすべて握りつぶす設計が常に正しいわけではありません。監査を必須にするのか、ログオン可用性を優先するのかを業務要件として決めます。
まとめ
ORA-00604は、Oracleの再帰SQL処理中に別のエラーが起きたことを示す入口です。まずORA-00604の次に出るエラーを読み、ログオン/DDLトリガー、権限不足、無効オブジェクト、PL/SQL行番号を確認します。
特にログオン時に発生する場合は、システムトリガーが原因になっていることがあります。本番では、原因トリガーを特定し、必要なら一時無効化、修正、再有効化、監視見直しまで行いましょう。

