【PL/SQL】DBMS_WARNINGの使い方|PLSQL_WARNINGS・PLW警告・CI/CDで警告をエラー化する方法

【PL/SQL】DBMS_WARNINGでコンパイル時の警告を制御する方法 PL/SQL

DBMS_WARNING は、PL/SQLのコンパイル時警告を確認・変更するためのOracle標準パッケージです。PL/SQLコンパイラは、実行を妨げるほどではないものの、将来の不具合、保守性低下、性能問題につながりうる書き方を PLW-nnnnn 形式の警告として出します。

警告は「表示して終わり」ではなく、開発時は広く有効化し、CI/CDでは危険な警告をエラー扱いにする、という運用にすると効果が出ます。この記事では、PLSQL_WARNINGSDBMS_WARNINGUSER_ERRORSALL_PLSQL_OBJECT_SETTINGS を使って、PL/SQL警告を開発・レビュー・リリースで扱う方法を整理します。コンパイルエラー全体の確認は PL/SQLコンパイル時エラーと警告の完全対処ガイド も参考にしてください。

この記事で扱うこと

  • PLSQL_WARNINGSDBMS_WARNING の関係
  • SEVERE / PERFORMANCE / INFORMATIONAL の分類
  • ENABLE:ALLERROR:06002 の使い方
  • SHOW ERRORS / USER_ERRORS での確認
  • ALL_PLSQL_OBJECT_SETTINGS で設定を確認する方法
  • CI/CDで警告をビルド失敗にする運用
  • 警告を無視しすぎないためのチームルール
スポンサーリンク

PL/SQLコンパイル時警告とは

PL/SQLコンパイル時警告は、コンパイルを止めるエラーではないものの、コード品質上の注意を示すメッセージです。公式ドキュメントでは、PL/SQL警告のメッセージコードは PLW-nnnnn 形式で、非推奨機能の利用、到達不能コード、予期しない動作につながりうる条件などが例として挙げられています。

エラーコンパイルに失敗し、オブジェクトが無効になります。
警告コンパイルは通るが、将来のバグや性能問題の兆候を示します。
PLWコードPLW-06002 のように、PLW-nnnnn形式で表示されます。
運用方針開発時は広く出し、リリース時は重要警告をエラー化します。

警告カテゴリ

PL/SQL警告は、大きく SEVEREPERFORMANCEINFORMATIONAL に分かれます。すべてを同じ重みで扱うと運用しづらいので、まず重大度で方針を分けます。

SEVERE予期しない動作や誤った結果につながりうる重大な警告です。
PERFORMANCE性能問題につながる可能性がある警告です。
INFORMATIONAL保守性や読みやすさに関する情報的な警告です。
特定PLWERROR:06002 のように、個別警告をエラー扱いできます。

PLSQL_WARNINGSをALTER SESSIONで設定する

もっとも基本的な方法は、セッションの PLSQL_WARNINGS パラメータを変更することです。開発時は ENABLE:ALL で広く検出し、CIやリリース前検査では重要な警告を ERROR 扱いにします。

alter-session-plsql-warnings.sql
-- 開発時: すべての警告を有効化
ALTER SESSION SET PLSQL_WARNINGS = 'ENABLE:ALL';

-- 重大警告だけ有効化
ALTER SESSION SET PLSQL_WARNINGS = 'ENABLE:SEVERE';

-- 到達不能コード PLW-06002 をエラー扱いにする
ALTER SESSION SET PLSQL_WARNINGS = 'ENABLE:ALL', 'ERROR:06002';

-- 一時的にすべて無効化
ALTER SESSION SET PLSQL_WARNINGS = 'DISABLE:ALL';
注意: ALTER SYSTEM で全体設定を変えると影響範囲が大きくなります。まずは ALTER SESSION やコンパイル単位の設定で運用を固めるのが安全です。

DBMS_WARNINGで設定する

DBMS_WARNING を使うと、PL/SQLやSQL*Plusスクリプトの中から警告設定を変更・確認できます。複数のコンパイルスクリプトを実行する場合、元の設定を退避して一時的に変更し、最後に戻す運用がしやすくなります。

dbms-warning-basic.sql
BEGIN
  -- すべての警告を有効化
  DBMS_WARNING.SET_WARNING_SETTING_STRING('ENABLE:ALL', 'SESSION');

  -- PERFORMANCEだけ無効化
  DBMS_WARNING.SET_WARNING_SETTING_CATEGORY('PERFORMANCE', 'DISABLE', 'SESSION');

  -- 現在の設定を確認
  DBMS_OUTPUT.PUT_LINE(DBMS_WARNING.GET_WARNING_SETTING_STRING());
END;
/

DBMS_OUTPUT で設定を表示する場合は、SQL*PlusやSQLcl側の SET SERVEROUTPUT ON も必要です。DBMS_OUTPUTの基本は DBMS_OUTPUTの使い方完全ガイド にまとめています。

現在の警告設定を確認する

現在セッションの設定は DBMS_WARNING.GET_WARNING_SETTING_STRING() で確認できます。オブジェクトごとのコンパイル設定は、ALL_PLSQL_OBJECT_SETTINGSUSER_PLSQL_OBJECT_SETTINGS で確認します。

check-warning-settings.sql
-- 現在セッションの警告設定
SELECT DBMS_WARNING.GET_WARNING_SETTING_STRING() AS warning_setting
FROM dual;

-- オブジェクトごとのPLSQL_WARNINGS設定
SELECT
  owner,
  name,
  type,
  plsql_warnings
FROM all_plsql_object_settings
WHERE owner = USER
ORDER BY name, type;

リリース前に、重要パッケージだけ警告設定が違う、古い設定で再コンパイルされている、といった状態を検出できます。

警告を発生させて確認する

警告が有効になっているか確認するには、到達不能コードのような分かりやすい例で試すと理解しやすいです。Oracle公式の例でも、到達不能コードに対する PLW-06002 が紹介されています。

unreachable-code-warning.sql
ALTER SESSION SET PLSQL_WARNINGS = 'ENABLE:ALL';

CREATE OR REPLACE PROCEDURE unreachable_code_demo AS
  l_flag CONSTANT BOOLEAN := TRUE;
BEGIN
  IF l_flag THEN
    DBMS_OUTPUT.PUT_LINE('TRUE branch');
  ELSE
    DBMS_OUTPUT.PUT_LINE('This branch is unreachable');
  END IF;
END;
/

SHOW ERRORS PROCEDURE unreachable_code_demo

SQL*PlusやSQLclでは SHOW ERRORS、SQLで確認するなら USER_ERRORS を使います。

query-user-errors-warnings.sql
SELECT
  name,
  type,
  line,
  position,
  attribute,
  message_number,
  text
FROM user_errors
WHERE name = 'UNREACHABLE_CODE_DEMO'
ORDER BY sequence;

特定警告をエラー化する

警告の中には、チームとして許容したくないものがあります。その場合は ERROR:警告番号 を指定し、該当警告が出たらコンパイルを失敗させます。たとえば、到達不能コードをリリース禁止にしたい場合は ERROR:06002 を使います。

warning-as-error.sql
ALTER SESSION SET PLSQL_WARNINGS = 'ENABLE:ALL', 'ERROR:06002';

CREATE OR REPLACE PROCEDURE unreachable_code_demo AS
  l_flag CONSTANT BOOLEAN := TRUE;
BEGIN
  IF l_flag THEN
    DBMS_OUTPUT.PUT_LINE('TRUE branch');
  ELSE
    DBMS_OUTPUT.PUT_LINE('This branch is unreachable');
  END IF;
END;
/

-- PLW-06002がERROR扱いになり、コンパイル失敗として検出できる

最初から全警告をエラー化すると既存資産ではつらくなりがちです。まずは SEVERE や特定PLWだけをエラー化し、段階的に対象を広げるのが現実的です。

コンパイル単位で設定する

全セッションではなく、特定プロシージャやパッケージだけ警告設定を変えてコンパイルできます。既存システムで段階的に厳格化する場合に使いやすい方法です。

compile-unit-warning-setting.sql
ALTER PROCEDURE unreachable_code_demo
  COMPILE PLSQL_WARNINGS = 'ENABLE:ALL', 'ERROR:06002'
  REUSE SETTINGS;

ALTER PACKAGE target_pkg
  COMPILE PACKAGE PLSQL_WARNINGS = 'ENABLE:SEVERE'
  REUSE SETTINGS;

ALTER PACKAGE target_pkg
  COMPILE BODY PLSQL_WARNINGS = 'ENABLE:ALL', 'ERROR:06002'
  REUSE SETTINGS;

REUSE SETTINGS を使うと、既存のコンパイル設定を引き継ぎながら再コンパイルできます。ただし、何を引き継いでいるか分からない状態になりやすいので、リリーススクリプトでは意図した設定を明示するほうが安全です。

CI/CDで警告を検出する

PL/SQLのコンパイル警告は、レビューやCI/CDで検出してこそ価値があります。ビルド用セッションで PLSQL_WARNINGS を設定し、コンパイル後に USER_ERRORS を確認します。警告を許容しない対象では、警告が残っていたらビルド失敗にします。

ci-check-plsql-warnings.sql
ALTER SESSION SET PLSQL_WARNINGS = 'ENABLE:ALL', 'ERROR:06002';

-- ここでパッケージやプロシージャをコンパイルする
-- @packages/target_pkg.pks
-- @packages/target_pkg.pkb

-- 警告・エラーを確認
SELECT
  name,
  type,
  line,
  position,
  attribute,
  text
FROM user_errors
WHERE attribute IN ('ERROR', 'WARNING')
ORDER BY name, type, sequence;

-- CI側では、結果行があれば失敗扱いにする

PL/SQLのデプロイ自動化やCI/CD連携は PL/SQLコードデプロイの自動化とEdition管理 とあわせて考えると実務に落とし込みやすいです。

警告ポリシーの例

チームで警告を扱う場合、すべてを一気に厳格化するより、段階を決めると導入しやすくなります。

開発環境ENABLE:ALL で広く警告を出します。
既存資産まず SEVERE と特定PLWだけを修正対象にします。
新規コード警告ゼロを原則にし、必要な例外はレビューで理由を残します。
CI/CD到達不能コードなど、明確に危険な警告は ERROR 扱いにします。
リリース前USER_ERRORSALL_PLSQL_OBJECT_SETTINGS を保存して差分確認します。

DBMS_WARNINGで設定を退避・復元する

複雑なコンパイルスクリプトでは、元の警告設定を退避してから一時的に変更し、最後に戻すと安全です。Oracle公式でも、DBMS_WARNINGは複数スクリプトで異なる警告設定を扱う場合に役立つと説明されています。

save-and-restore-warning-setting.sql
DECLARE
  l_old_setting VARCHAR2(4000);
BEGIN
  l_old_setting := DBMS_WARNING.GET_WARNING_SETTING_STRING();

  DBMS_WARNING.SET_WARNING_SETTING_STRING(
    warning_value => 'ENABLE:ALL, ERROR:06002',
    scope         => 'SESSION'
  );

  -- ここで対象オブジェクトをコンパイルする
  EXECUTE IMMEDIATE 'ALTER PROCEDURE unreachable_code_demo COMPILE';

  DBMS_WARNING.SET_WARNING_SETTING_STRING(l_old_setting, 'SESSION');
EXCEPTION
  WHEN OTHERS THEN
    DBMS_WARNING.SET_WARNING_SETTING_STRING(l_old_setting, 'SESSION');
    RAISE;
END;
/

よくある落とし穴

警告を見ていないコンパイル成功だけを見ていると、警告が放置されます。
全警告を一気にエラー化既存資産では失敗が多くなります。対象PLWを絞って段階導入します。
SYSTEM設定を安易に変更影響範囲が広いため、まずSESSIONやコンパイル単位で検証します。
USER_ERRORSを見ないSHOW ERRORSだけでなく、CIではUSER_ERRORS/ALL_ERRORSをSQLで確認します。
設定差分を残さないALL_PLSQL_OBJECT_SETTINGSで、どの設定でコンパイルされたか確認できるようにします。

DBMS_TRACEやDBMS_APPLICATION_INFOとの違い

DBMS_WARNING はコンパイル時の品質チェックです。実行経路を追うなら DBMS_TRACE、運用監視でセッション状態を見るなら DBMS_APPLICATION_INFO を使います。開発から本番運用までの観測性を高めるには、それぞれの役割を分けます。

実行経路の追跡は DBMS_TRACEの使い方、運用観測性の強化は DBMS_APPLICATION_INFOで運用観測性を底上げ で扱っています。

よくある質問

Q. 警告は無視しても動きますか?
A. 多くの場合は動きます。ただし、将来のバグや性能問題の兆候なので、新規コードでは警告ゼロを目指すのが安全です。
Q. ERROR:06002とは何ですか?
A. PLW-06002をエラー扱いにする指定です。到達不能コードをコンパイル失敗として検出できます。
Q. ALTER SESSIONとDBMS_WARNINGはどちらを使うべきですか?
A. 手動や単純なスクリプトではALTER SESSIONで十分です。複雑なコンパイル処理で設定を退避・復元したい場合はDBMS_WARNINGが便利です。
Q. 既存システムでENABLE:ALLにしたら警告が大量に出ました。
A. まずSEVEREや特定PLWに絞り、新規コードから厳格化します。既存資産は段階的に直すのが現実的です。
Q. CIでどう判定しますか?
A. コンパイル後にUSER_ERRORS/ALL_ERRORSを検索し、ERRORまたは対象WARNINGが残っていたら失敗扱いにします。

まとめ

DBMS_WARNINGPLSQL_WARNINGS を使うと、PL/SQLのコンパイル時警告を開発・レビュー・CI/CDで制御できます。開発時は ENABLE:ALL で広く検出し、リリース前には重要な警告を ERROR 扱いにして品質ゲートにするのが効果的です。

警告はエラーではありませんが、無視し続けると保守性低下や将来の不具合につながります。SHOW ERRORSUSER_ERRORSALL_PLSQL_OBJECT_SETTINGS を確認し、どの警告を許容し、どの警告をビルド失敗にするかをチームルールとして決めておきましょう。

参考: Oracle Database PL/SQL Language Reference – Compile-Time Warnings