10.

DB2 で自動番号付け (autoincrement) する方法完全ガイド

編集
この記事の要点
  • DB2 の自動採番は GENERATED ALWAYS AS IDENTITY / GENERATED BY DEFAULT AS IDENTITY
  • 初期値・増分: START WITH 1 INCREMENT BY 1NO CACHE / NO CYCLE 等のオプション
  • SEQUENCE オブジェクトも併用可: CREATE SEQUENCE seq_name START WITH 1NEXTVAL FOR seq_name
  • 値リセット: ALTER TABLE T ALTER COLUMN id RESTART WITH 1
  • MySQL の AUTO_INCREMENT、PostgreSQL の SERIAL / GENERATED ... AS IDENTITY と概念は同等

1. DB2 の IDENTITY 列

DB2 では列に IDENTITY 属性を付けて自動採番します。SQL 標準の GENERATED ... AS IDENTITY 構文に準拠しています。

-- GENERATED ALWAYS: アプリは絶対値を入れられない(DB が必ず採番)
CREATE TABLE customers (
    id          INTEGER NOT NULL
                  GENERATED ALWAYS AS IDENTITY
                  (START WITH 1 INCREMENT BY 1 NO CACHE),
    name        VARCHAR(100) NOT NULL,
    created_at  TIMESTAMP NOT NULL DEFAULT CURRENT TIMESTAMP,
    PRIMARY KEY (id)
);

-- INSERT は id を指定しない
INSERT INTO customers (name) VALUES ('Taro');
INSERT INTO customers (name) VALUES ('Hanako');

SELECT * FROM customers;
-- 1 | Taro   | 2026-05-17 10:00:00
-- 2 | Hanako | 2026-05-17 10:00:01

2. ALWAYS vs BY DEFAULT

属性挙動用途
GENERATED ALWAYS AS IDENTITYアプリ指定不可。OVERRIDING SYSTEM VALUE で例外的に上書きマスタテーブル(厳格)
GENERATED BY DEFAULT AS IDENTITYアプリ指定可(指定しなければ自動)移行 / インポート時
-- ALWAYS の場合
INSERT INTO customers (id, name) VALUES (100, 'Direct');
-- SQL0798N: GENERATED ALWAYS で AS IDENTITY と定義された列に値を割り当てる
-- ことはできません

-- 上書きするには
INSERT INTO customers (id, name)
    OVERRIDING SYSTEM VALUE
    VALUES (100, 'Direct');

-- BY DEFAULT の場合は普通に
CREATE TABLE products (
    id INTEGER NOT NULL
        GENERATED BY DEFAULT AS IDENTITY (START WITH 1),
    name VARCHAR(100),
    PRIMARY KEY (id)
);
INSERT INTO products (id, name) VALUES (1000, 'Direct OK');
INSERT INTO products (name) VALUES ('Auto');

3. オプションを使いこなす

CREATE TABLE orders (
    id BIGINT NOT NULL
        GENERATED ALWAYS AS IDENTITY (
            START WITH 1000          -- 開始値
            INCREMENT BY 10          -- 増分
            MINVALUE 1000
            MAXVALUE 9999999999
            NO CYCLE                 -- 最大値到達でエラー
            CACHE 50                 -- 採番を 50 個ずつメモリにキャッシュ(高速化)
            ORDER                    -- 厳密に順序保証(パフォーマンス低下)
        ),
    customer_id INTEGER,
    PRIMARY KEY (id)
);

CACHE はパフォーマンスを上げますが、サーバ再起動時にキャッシュ分が欠番になります(許容できる場合がほとんど)。順序を厳密に守りたいなら NO CACHE + ORDER

4. SEQUENCE オブジェクト

テーブル列に紐づかない、独立した採番器を作りたい場合は SEQUENCE:

CREATE SEQUENCE order_seq
    AS INTEGER
    START WITH 1
    INCREMENT BY 1
    NO CYCLE
    CACHE 20;

-- 次の値を取得
SELECT NEXTVAL FOR order_seq FROM SYSIBM.SYSDUMMY1;

-- 同一文中の現在値を再利用
INSERT INTO orders (order_no, code)
VALUES (NEXTVAL FOR order_seq, 'A');
INSERT INTO order_items (order_no, item)
VALUES (PREVVAL FOR order_seq, 'item1');

-- 変更
ALTER SEQUENCE order_seq RESTART WITH 1000;
ALTER SEQUENCE order_seq INCREMENT BY 5;

-- 削除
DROP SEQUENCE order_seq;

5. リセット(RESTART)

-- IDENTITY 列の次の値を変更
ALTER TABLE customers ALTER COLUMN id RESTART WITH 1;

-- 既存最大値の次から始め直す
SELECT MAX(id) FROM customers;  -- 例: 1234
ALTER TABLE customers ALTER COLUMN id RESTART WITH 1235;

-- 増分を変更
ALTER TABLE customers ALTER COLUMN id SET INCREMENT BY 10;

6. 生成された ID を取得

-- 直前の INSERT で採番された ID
SELECT IDENTITY_VAL_LOCAL() FROM SYSIBM.SYSDUMMY1;

-- アプリから(PreparedStatement)
-- Java 例:
PreparedStatement ps = conn.prepareStatement(
    "INSERT INTO customers (name) VALUES (?)",
    Statement.RETURN_GENERATED_KEYS);
ps.setString(1, "Taro");
ps.executeUpdate();
try (ResultSet keys = ps.getGeneratedKeys()) {
    if (keys.next()) {
        long id = keys.getLong(1);
    }
}

-- SELECT FROM FINAL TABLE で同一文内で取得
SELECT id FROM FINAL TABLE (
    INSERT INTO customers (name) VALUES ('Taro')
);

7. 他 RDBMS との比較

RDBMS採番構文備考
DB2GENERATED ALWAYS AS IDENTITYSQL 標準
MySQLAUTO_INCREMENT独自構文、SEQUENCE 無し
PostgreSQLSERIAL / GENERATED ... AS IDENTITY後者が SQL 標準で推奨
OracleGENERATED AS IDENTITY (12c+) / SEQUENCE12c 未満は SEQUENCE + TRIGGER
SQL ServerIDENTITY(1,1)独自構文

8. INSERT 時の挙動 / 注意点

-- ROLLBACK しても採番は戻らない(欠番が出る)
INSERT INTO customers (name) VALUES ('A');   -- id=1
INSERT INTO customers (name) VALUES ('B');   -- id=2
ROLLBACK;
INSERT INTO customers (name) VALUES ('C');   -- id=3(1,2 は欠番)

-- 一意性 + 採番は別概念
-- IDENTITY は採番するが UNIQUE 保証はしない → PRIMARY KEY を別途指定

-- LOAD ユーティリティで取り込み時
-- BY DEFAULT なら入力値を使い、ALWAYS なら IGNORE オプションで採番
LOAD FROM input.del OF DEL MODIFIED BY GENERATEDIGNORE
    INSERT INTO customers;

FAQ

Q: 採番がスキップして「欠番」が出る
A: ROLLBACK / CACHE 設定 / 接続切断で発生。連番性は仕様上保証されません。請求書番号のような連番が必要なら別テーブル + ロックで採番を。

Q: 既存テーブルに後から IDENTITY を付けたい
A: ALTER TABLE T ALTER COLUMN id SET GENERATED BY DEFAULT AS IDENTITY (START WITH N)。N は MAX(id) + 1

Q: 採番列に NULL を入れたい
A: 不可。NOT NULL 必須。NULL の概念が無いなら別カラム設計を見直す。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  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文を生成する方法