ORA-04088: error during execution of trigger は、Oracleのトリガー実行中に別のエラーが発生したことを示すメッセージです。INSERT、UPDATE、DELETE、DDL、ログオン処理などでトリガーが自動実行され、その中のSQLやPL/SQLが失敗した時に出ます。
ORA-04088自体は「トリガーの実行中に失敗した」という入口です。本当の原因は、前後に出る ORA-06512 の行番号、ORA-01031 の権限不足、ORA-06502 の値エラー、ORA-04091 のミューテーティングテーブルなどです。この記事では、エラースタックの読み方、トリガー本文の確認、:NEW/:OLD、権限、無効オブジェクトまで順に整理します。
- ORA-04088が何を示しているか
- ORA-06512の行番号からトリガー内の失敗箇所を探す方法
- DBA_TRIGGERS、DBA_SOURCE、DBA_ERRORSの確認SQL
- :NEW/:OLD、権限不足、無効オブジェクト、例外処理ミスの切り分け
- トリガーを一時無効化する時の注意点
この記事で扱う範囲
この記事では、DMLトリガーやシステムトリガーの実行中にORA-04088が出た時の調査手順を扱います。トリガーの種類や基本構文は Oracleトリガー完全ガイド、トリガー一覧の取得は トリガー情報を取得するSQL文 も参考にしてください。
最初に結論:ORA-04088の直前・直後のエラーを見る
ORA-04088は、トリガー実行時エラーの総称に近いメッセージです。ORA-04088の1行だけではなく、同時に出ているトリガー名、ORA-06512の行番号、直前に出たORAエラーを確認します。
- INSERT、UPDATE、DELETE、DDL、LOGONのどの操作で発生したか
- すべての行で出るのか、特定データだけで出るのか
- トリガー対象表のDMLなのか、トリガー内で呼んだ別オブジェクトなのか
- 無効化せずに入力値・権限・依存オブジェクト修正で直せるか
ORA-00604と一緒に出る場合は ORA-00604の原因と解決方法、行番号の読み方は ORA-06512の原因と読み方 を確認してください。
エラーメッセージの読み方
典型的には、ORA-04088の前後にトリガー名と行番号が表示されます。次の例では、APP.ORDERS_BIU_TRG の12行目付近で値エラーが起きています。
ORA-06502: PL/SQL: numeric or value error: character string buffer too small ORA-06512: at "APP.ORDERS_BIU_TRG", line 12 ORA-04088: error during execution of trigger 'APP.ORDERS_BIU_TRG'
この場合、調査の中心はORA-04088ではなく、ORA-06502 とトリガー12行目です。値エラーの切り分けは ORA-06502の原因と解決方法 も参考になります。
確認SQL
トリガーの状態とイベントを確認する
まず、対象トリガーがどの表・イベントで動くのか、状態がVALID/ENABLEDなのかを確認します。DMLトリガーだけでなく、DDLトリガーやLOGONトリガーが関係する場合もあります。
SELECT owner,
trigger_name,
trigger_type,
triggering_event,
table_owner,
table_name,
status
FROM dba_triggers
WHERE owner = 'APP'
AND trigger_name = 'ORDERS_BIU_TRG';
トリガー本文を行番号付きで確認する
ORA-06512の行番号と照らし合わせるため、DBA_SOURCE で本文を行番号付きで確認します。権限がない場合は ALL_SOURCE や USER_SOURCE を使います。
SELECT line,
text
FROM dba_source
WHERE owner = 'APP'
AND name = 'ORDERS_BIU_TRG'
AND type = 'TRIGGER'
ORDER BY line;
コンパイルエラーを確認する
トリガーがINVALIDになっている、または再コンパイルに失敗している場合は、DBA_ERRORS を確認します。無効なトリガーはORA-04098として出ることもあります。
SELECT owner,
name,
type,
line,
position,
text
FROM dba_errors
WHERE owner = 'APP'
AND name = 'ORDERS_BIU_TRG'
ORDER BY sequence;
トリガーが無効な場合は ORA-04098の原因と解決方法 と関連します。
依存オブジェクトの状態を確認する
トリガー内で呼び出すプロシージャ、パッケージ、ビューなどがINVALIDになっている場合もあります。対象スキーマの無効オブジェクトを確認します。
SELECT owner,
object_name,
object_type,
status
FROM dba_objects
WHERE owner = 'APP'
AND status = 'INVALID'
ORDER BY object_type, object_name;
原因別の切り分け
:NEW/:OLDの使い方ミス
DMLトリガーでは、INSERT/UPDATE/DELETEごとに :NEW と :OLD の使える値が変わります。DELETEで :NEW を前提にした処理、INSERTで :OLD を参照する処理、NULLを想定していない処理はエラーの原因になります。
- INSERT時は主に
:NEWを使う - UPDATE時は
:OLDと:NEWの両方を比較できる - DELETE時は主に
:OLDを使う - 文レベルトリガーでは行ごとの
:NEW/:OLDは使えない
CREATE OR REPLACE TRIGGER app.orders_biu_trg
BEFORE INSERT OR UPDATE ON app.orders
FOR EACH ROW
BEGIN
IF INSERTING THEN
:NEW.created_at := NVL(:NEW.created_at, SYSDATE);
END IF;
IF UPDATING THEN
:NEW.updated_at := SYSDATE;
END IF;
END;
/
権限不足
トリガー内で別スキーマの表やパッケージを参照している場合、実行時に権限不足が出ることがあります。PL/SQL内ではロール経由の権限が効かない場面があるため、直接付与された権限を確認します。
SELECT grantee,
owner,
table_name,
privilege
FROM dba_tab_privs
WHERE grantee = 'APP'
ORDER BY owner, table_name, privilege;
権限不足は ORA-01031完全ガイド で詳しく扱っています。
ミューテーティングテーブル
行トリガー内で、トリガー対象表を再度SELECT/UPDATEすると ORA-04091 につながることがあります。この場合は、コンパウンドトリガー、文レベルトリガー、別設計への変更を検討します。
詳細は ORA-04091の原因と解決方法 を確認してください。
例外処理の設計ミス
トリガー内で WHEN OTHERS THEN NULL のように例外を握りつぶすと、業務データの不整合を隠すことがあります。逆に、監査ログ失敗で業務DML全体を止める設計がよいかどうかも要件次第です。
BEGIN
INSERT INTO app.audit_log(table_name, changed_at)
VALUES ('ORDERS', SYSDATE);
EXCEPTION
WHEN OTHERS THEN
-- 握りつぶすのか、再送出するのかは要件で決める
RAISE;
END;
トリガーを一時無効化する場合
本番障害で緊急回避が必要な場合、原因トリガーを一時的に無効化することがあります。ただし、監査、採番、整合性補完、履歴作成などを担っているトリガーを止めると、データ不整合につながる可能性があります。
- 無効化するトリガー名を確認した
- トリガーが担っている業務処理を確認した
- 無効化中に発生するDMLの影響を確認した
- 入力値修正、権限付与、依存オブジェクト再コンパイルで回避できないか確認した
- 無効化中に実行されたDMLを後で再処理・補正する必要があるか確認した
- 再有効化コマンドと戻し担当を決めた
- 修正後に再実行・再検証するSQLを決めた
ALTER TRIGGER app.orders_biu_trg DISABLE; -- 修正・検証後 ALTER TRIGGER app.orders_biu_trg ENABLE;
やってはいけない対応
本番対応チェックリスト
- エラースタック全体を控えた
- トリガー名とORA-06512の行番号を確認した
- DBA_TRIGGERSでイベント、対象表、状態を確認した
- DBA_SOURCEで該当行の処理を確認した
- DBA_ERRORSでコンパイルエラーを確認した
- :NEW/:OLD、NULL、型変換、文字列長を確認した
- 権限不足や無効オブジェクトを確認した
- 無効化する場合は影響範囲と戻し手順を決めた
再発防止
ORA-04088を防ぐには、トリガーに複雑な業務ロジックを詰め込みすぎないことが重要です。トリガー内のSQLは失敗時の影響範囲が大きく、アプリ側からは見えにくいことがあります。
監査や履歴のようにトリガーが向いている処理でも、例外処理、権限、依存オブジェクト、テストデータ、無効化手順をセットで用意します。PL/SQL側のトリガー設計は PL/SQLトリガー完全ガイド も参考になります。
まとめ
ORA-04088は、Oracleのトリガー実行中に別エラーが起きたことを示すメッセージです。まずエラースタック全体を読み、トリガー名、ORA-06512の行番号、直前のORAエラーを確認します。
調査では、DBA_TRIGGERS、DBA_SOURCE、DBA_ERRORS、DBA_OBJECTS を使い、:NEW/:OLD、権限不足、無効オブジェクト、ミューテーティングテーブル、例外処理を切り分けます。本番でトリガーを無効化する場合は、影響範囲と戻し手順を必ず確認しましょう。
