ERROR: integer out of range は、integer 型(-2,147,483,648〜2,147,483,647)に収まらない値を作ろうとしたときのエラーです。 多いのは次の3つです。

原因 エラー文 直し方
serial の ID が上限に届いた nextval: reached maximum value of sequence "..." (2147483647) 列を bigint に。シーケンスも bigint に
掛け算・足し算の途中であふれた integer out of range 片方を ::bigint にしてから計算
アプリから大きな値を入れた integer out of range、value "..." is out of range for type integer 列を bigint に

確認環境:PostgreSQL 16.15、psycopg 3.3.6、PostgreSQL JDBC Driver 42.7.2(確認日 2026年10月11日)。

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「PostgreSQL integer out of rangeの原因と直し方」

原因1:serial の ID が上限に届いた

=> SELECT setval('ior_id_seq', 2147483646);      -- 上限の手前まで進める
=> INSERT INTO ior (v) VALUES (1) RETURNING id;
     id
------------
 2147483647
=> INSERT INTO ior (v) VALUES (2) RETURNING id;
ERROR:  nextval: reached maximum value of sequence "ior_id_seq" (2147483647)

serial の場合、エラー文は integer out of range ではなく、シーケンスの上限のエラーになりました。 serial は「integer の列」と「AS integer のシーケンス」を作るためです(PostgreSQL 公式ドキュメント)。シーケンスが bigint で、列が integer の場合は、integer out of range になりました。

列 シーケンス 上限を超えたときのエラー
integer(serial) integer nextval: reached maximum value of sequence
integer bigint(手で作った) integer out of range

あとどれくらい残っているか

SELECT sequencename, data_type, last_value,
       round(100.0 * coalesce(last_value, 0) / max_value, 4) AS used_pct
FROM pg_sequences;

data_type が integer のシーケンスで、used_pct が大きいものが要注意です。テストや移行でシーケンスを大きく進めた、1日に大量の行を入れては消す、といったテーブルでは、行数が少なくても番号だけが進みます。

落とし穴:列を bigint にしても、serial のシーケンスは integer のまま

ALTER TABLE ior ALTER COLUMN id TYPE bigint;
=> SELECT sequencename, data_type, max_value FROM pg_sequences WHERE sequencename = 'ior_id_seq';
 sequencename | data_type | max_value
--------------+-----------+------------
 ior_id_seq   | integer   | 2147483647        ← シーケンスは integer のまま

=> INSERT INTO ior (v) VALUES (3) RETURNING id;
ERROR:  nextval: reached maximum value of sequence "ior_id_seq" (2147483647)

列を bigint に変えても、serial が作ったシーケンスの型は変わらず、同じエラーが続きました。 シーケンスも変えます。

ALTER SEQUENCE ior_id_seq AS bigint;
=> INSERT INTO ior (v) VALUES (3) RETURNING id;
     id
------------
 2147483648                                     ← 動いた
列の作り方 ALTER COLUMN ... TYPE bigint のあと
serial シーケンスは integer のまま。ALTER SEQUENCE ... AS bigint が別に必要
GENERATED ALWAYS AS IDENTITY シーケンスも bigint になった(確認環境)

新しく作るテーブルは、最初から bigint GENERATED ALWAYS AS IDENTITY(または bigserial)にしておくのが確実です。公式ドキュメントでも、テーブルの寿命の間に 2^31 個を超える ID を使う見込みがあるなら、bigserial を使うよう書かれています。serial と IDENTITY の違いは、関連記事の「PostgreSQL連番|serialとIDENTITYの違いとsetval修正」で扱っています。

外部キーの列も忘れずに

注文テーブルの customer_id のように、この ID を参照している子のテーブルの列も integer のままだと、ID が上限を超えた行を参照するときに、子のテーブル側で同じエラーになります。親と子の列を一緒に変えます。

bigint への変更にかかる時間とロック

3,000,000 行(214MB)のテーブルで、ALTER TABLE ... ALTER COLUMN id TYPE bigint を実行しました。

項目 結果(確認環境)
かかった時間 2.4 秒
テーブルの作り直し あり(pg_relation_filenode の値が変わった)
実行中のロック AccessExclusiveLock
実行中の別の接続の SELECT canceling statement due to lock timeout(lock_timeout = '1s' で待たせたとき)

integer から bigint への変更は、テーブル全体を作り直し、その間は SELECT も待たされました。 公式ドキュメントでも、型の変更は原則としてテーブルとインデックスの作り直しが必要で、ALTER TABLE は ACCESS EXCLUSIVE のロックを取るとされています。時間は行数・インデックスの数・ディスクの速さで変わるので、本番と同じくらいのデータで、事前に時間を測るのが安全です。作り直しの間は、一時的にディスクも余分に使います。

対策 内容
上限に届く前に変える pg_sequences で残りを定期的に確認する
メンテナンスの時間に実行 止められる時間に合わせる
lock_timeout を付けて実行 ほかの処理を長く止めない(取れなければやり直す)

原因2:掛け算・足し算の途中であふれた

=> SELECT 50000 * 50000;
ERROR:  integer out of range

=> SELECT 50000::bigint * 50000;
  ?column?
------------
 2500000000

=> SELECT 2147483647 + 1;
ERROR:  integer out of range

integer どうしの計算の結果は integer なので、途中であふれました。 単価×数量のような計算は、片方を ::bigint(または ::numeric)にしてから計算します。

計算 結果の型 あふれるか
int * int integer あふれる
int::bigint * int bigint あふれない
sum(int の列) bigint 確認環境では 2147483647 を2つ足して 4294967294 と動いた

sum は integer の列でも bigint で返るので、合計ではあふれません。あふれるのは、合計する前の、1行ごとの掛け算です。

原因3:大きな値を入れた

=> INSERT INTO ior (id, v) VALUES (1, 3000000000);
ERROR:  integer out of range

=> INSERT INTO ior (id, v) VALUES (1, '3000000000');
ERROR:  value "3000000000" is out of range for type integer

=> INSERT INTO ior3 VALUES (40000);          -- smallint の列
ERROR:  smallint out of range

文字列として渡すと、value "..." is out of range for type integer という別の文になりました。 smallint(-32,768〜32,767)では smallint out of range です。

Java 側でも起きる

操作 結果(確認環境)
bigint の列の値 2147483648 を rs.getInt() PSQLException: Bad value for type int : 2147483648
同じ値を rs.getLong() 2147483648
integer の列に setLong(1, 3000000000L) ERROR: integer out of range(SQLState 22003)

DB の列を bigint に変えたら、Java の int の変数・getInt も long・getLong に変えます。 DB だけ変えても、アプリの読み取りで止まります。

確認の手順(チェックリスト)

順番 確認すること 方法
1 どのエラー文か nextval: reached maximum(シーケンス)か integer out of range
2 ID なら、残りはどれくらいか pg_sequences の last_value と max_value
3 計算なら 1行ごとの掛け算を ::bigint に
4 bigint に変える 列とシーケンスの両方、外部キーの列も
5 変更の時間とロック 同じくらいのデータで事前に測る
6 アプリ int・getInt を long・getLong に

よくある質問

Q. SQLSTATE は何ですか。 A. integer out of range は 22003(numeric_value_out_of_range)です。シーケンスの上限のエラーは 2200H(sequence_generator_limit_exceeded)でした。

Q. ID を最初から振り直せばよいですか。 A. 使われていない番号から振り直す方法もありますが、ほかのテーブルやアプリが ID を保持していると、整合性が崩れます。bigint に変えるのが確実です。

まとめ

  • integer(約21億)に収まらない値を作ったエラー
  • serial の ID は、シーケンスの上限のエラー(nextval: reached maximum value)で出る
  • 列を bigint にしても、serial のシーケンスは integer のまま。ALTER SEQUENCE ... AS bigint も実行する
  • bigint への変更はテーブルを作り直し、SELECT も止まる。事前に時間を測る
  • 計算は1行ごとの掛け算であふれる。::bigint にしてから計算(sum は bigint)
  • Java の getInt も getLong に

参考・出典

確認日はいずれも 2026年10月11日です。

  • PostgreSQL 16 Documentation「Numeric Types」(Serial Types):https://www.postgresql.org/docs/16/datatype-numeric.html
  • PostgreSQL 16 Documentation「ALTER TABLE」:https://www.postgresql.org/docs/16/sql-altertable.html

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「PostgreSQL integer out of rangeの原因と直し方」

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?