15.

IBM Db2 よく見る SQL エラー一覧 — SQL0911N / SQL0204N / SQL0303N / SQL0805N

編集
この記事の要点
  • Db2 のエラーは SQLCODE (数値) と SQLSTATE (5 桁) のペアで返る。クライアントに表示されるのは SQL0911N のような形式
  • 末尾の N = エラー、W = 警告、C = 致命的システムエラー
  • 頻出: SQL0911N デッドロック / SQL0204N 未定義オブジェクト / SQL0303N 型変換不可 / SQL0805N パッケージ見つからない
  • メッセージ参照は db2 ? SQL0911N で詳細表示が一番手早い
  • 網羅は IBM Documentation (旧 Knowledge Center) の「SQL message reference」を参照

Db2 エラーの読み方

Db2 がエラーで返すメッセージは次のような形式です。

SQL0911N  The current transaction has been rolled back because of a deadlock
          or timeout.  Reason code "2".  SQLSTATE=40001
          ^^^^^^^^                                       ^^^^^
          SQLCODE: 文字列形式の番号                          SQLSTATE: 5 桁

SQLCODE  ... マイナス値はエラー、プラス値は警告、0 は正常
SQLSTATE ... SQL 標準準拠の 5 桁コード (40001 = serialization failure)
末尾    ... N (Error) / W (Warning) / C (Critical system error)

同じ条件は SQLCODE と SQLSTATE のどちらでも判定できます。アプリで分岐する場合はSQLSTATE で判定する方が他 DB との移植性が高いです。

頻出エラー一覧

SQLCODESQLSTATE意味典型原因
SQL0911N40001 / 57033デッドロック または ロックタイムアウト2 つ以上のセッションが互いを待つ / 長時間ロック保持
SQL0913N57033ロックタイムアウト (待機継続不可)LOCKTIMEOUT 設定値の超過
SQL0204N42704オブジェクト (表 / ビュー / インデックス) 未定義スキーマ指定漏れ、タイプミス、別ユーザー所有
SQL0206N42703列が存在しない列名タイプミス、JOIN 後の同名列指定ミス
SQL0303N42806FETCH/SELECT の 結果型が変数型と一致しないVARCHAR 列を INT 変数で受ける等
SQL0407N23502NULL 値を NOT NULL 列に入れた必須項目に値を渡し忘れ
SQL0530N23503外部キー違反親側に存在しない値で子側を更新
SQL0532N23504削除制約違反 (RESTRICT / NO ACTION)子から参照されている親行を削除
SQL0803N23505一意制約違反主キー / UNIQUE 索引重複
SQL0805N51002パッケージ (静的 SQL) が見つからないBIND されていない / NULLID 等の指定誤り
SQL5005C-システムエラー (致命的)DBM 起動に失敗 / インスタンス構成破損
SQL0964C57011トランザクション ログ満杯大量更新で LOGFILSIZ × LOGPRIMARY 超過
SQL0901N58004システムエラー (継続可能)内部一時障害。再実行で復旧することが多い
SQL0104N42601構文エラーキーワード綴り / カンマ落ち / カッコ閉じ忘れ

エラー番号からメッセージ詳細を引く

Db2 クライアントには ? コマンドが組み込まれており、エラー番号の説明文と推奨対応を表示できます。

$ db2 ? SQL0911N

SQL0911N  The current transaction has been rolled back because of a
          deadlock or timeout.  Reason code "<reason-code>".

Explanation: The current unit of work was involved in an unresolved
contention for use of an object and had to be rolled back. ...

User Response: To prevent this error, ...

# 数字だけでも引ける
$ db2 ? 911

# SQLSTATE からも
$ db2 ? 40001

SQL0911N の調査手順 (デッドロック)

本番で最頻出のエラー。SQLCODE と一緒に返る Reason Code で原因を切り分けます。

Reason Code意味
2デッドロック
68ロックタイムアウト
72関連リソースのロック取得失敗
-- デッドロック / タイムアウトのイベントモニタを有効化
CREATE EVENT MONITOR DLMON FOR LOCKING WRITE TO TABLE;
SET EVENT MONITOR DLMON STATE 1;

-- 発生時はイベント表に履歴が残る
SELECT * FROM SYSIBMADM.SNAP_LOCKS_RPT;
SELECT * FROM SYSIBMADM.LOCKWAIT;

-- ロックタイムアウト時間の確認 / 延長 (秒、-1 は無限待ち)
GET DBM CFG | grep -i LOCKTIMEOUT
UPDATE DB CFG FOR MYDB USING LOCKTIMEOUT 60;

SQL0204N (未定義オブジェクト) の調査

-- オブジェクト存在確認
SELECT TABSCHEMA, TABNAME
FROM   SYSCAT.TABLES
WHERE  TABNAME = 'ORDERS';

-- スキーマを指定して再実行
SELECT * FROM MYAPP.ORDERS FETCH FIRST 1 ROWS ONLY;

-- 現在のスキーマ
VALUES CURRENT SCHEMA;

-- 既定スキーマを明示的に切替
SET CURRENT SCHEMA = MYAPP;

SQL0805N (パッケージ未 BIND) の対処

JDBC / CLI ドライバを新規セットアップした際に頻発します。Db2 が提供する bind ファイルを BIND し直します。

$ db2 connect to MYDB
$ cd $HOME/sqllib/bnd

# CLI ドライバ用パッケージを BIND
$ db2 bind @db2cli.lst grant public CLIPKG 5

# JDBC 用
$ db2 bind @db2ubind.lst grant public
$ db2 bind @db2cli.lst   grant public

$ db2 terminate

アプリ側 (Java / JDBC) でのハンドリング

try {
    pstmt.executeUpdate();
} catch (SQLException e) {
    int code = e.getErrorCode();        // SQLCODE (符号付き整数)
    String state = e.getSQLState();     // SQLSTATE
    String msg   = e.getMessage();

    if ("40001".equals(state)) {
        // デッドロック / シリアライゼーション失敗 → リトライ
        retry();
    } else if ("23505".equals(state)) {
        // 一意制約違反 → ユーザに重複と表示
        throw new DuplicateException(msg);
    } else if (code == -407) {
        // NOT NULL 違反
        throw new ValidationException("必須項目未入力");
    } else {
        throw e;
    }
}

網羅性のあるリファレンス

  • IBM Documentation (旧 Knowledge Center) の「Db2 message reference」: SQL コードを Sxxxx 単位で全件記載
  • db2diag.log: ~/sqllib/db2dump/ に出力されるシステムログ。重大エラー時に必読
  • db2pd -d MYDB -locks: ロック状況のスナップショット

FAQ

Q: SQLCODE と SQLSTATE のどちらを見るべき?
A: 業務ロジックでハンドリングするならSQLSTATE。SQL 標準なので Oracle や PostgreSQL に移行しても同じコードが使えます。ベンダー固有のメッセージや調査時は SQLCODE で見ます。

Q: SQL0911N が頻発する
A: 業務処理の更新順序を揃えるのが定石。複数表を更新する際にすべての処理で「A → B → C」のように同じ順で取得することでデッドロックを根絶できます。

Q: 末尾の W は気にしなくていい?
A: 警告 (Warning) ですが、データ切り捨て (SQL0204W ではなく SQL0445W など) や暗黙変換はロジック不具合の兆候のことが多く、本番ログでは検知すべきです。

編集
Post Share
子ページ
  1. SQL3100W Column number XXX in row XXX is missing in the input file, but the target column is not nullable.
同階層のページ
  1. DB接続コマンド
  2. データベース一覧の確認
  3. テーブル一覧の確認
  4. テーブル定義の確認
  5. DBの設定確認
  6. テーブルスペースの容量の確認および拡張
  7. データ型
  8. 複数カラムのUPDATE
  9. カラムの追加/削除/変更
  10. 自動番号付け (autoincrement) する方法
  11. インデックスの作成
  12. シーケンスおよびインクリメント(ID列)の違いと確認方法
  13. create table文の生成
  14. 特定スキーマの全テーブルの全カラム情報を取得する方法
  15. 【DB2】エラー一覧
  16. 【DB2】テーブル定義からCREATE TABLE文を生成する方法

最近更新/作成されたページ