- データベース
PostgreSQL invalid input syntaxの直し方
ERROR: invalid input syntax for type integer: "" は、文字列を数値・日付などの型に変換しようとして、その型として読めなかったときのエラーです。 エラー文の最後の "" の中が、読めなかった値そのものです。"" なら空文字、"1,000" ならカンマ付きの数値が原因です。
| エラー文の値 | 原因 | 直し方 |
|---|---|---|
""(空文字) |
値が無いのを、NULL ではなく空文字で渡した | NULLIF(値, '') で NULL にする |
"1,000" |
桁区切りのカンマ | replace(値, ',', '') |
"12" |
全角数字 | normalize(値, NFKC) で半角に |
"12.5"(integer に) |
小数の文字列 | 数値として丸める・型を numeric に |
"2026年10月11日" |
日付の形式 | to_date(値, 'YYYY"年"MM"月"DD"日"') |
"はい"(boolean に) |
真偽値として読めない表記 | CASE で変換 |
確認環境:PostgreSQL 16.15、psycopg 3.3.6、PostgreSQL JDBC 42.7.2、比較に MySQL 8.0.46(確認日 2026年10月11日)。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「PostgreSQL invalid input syntaxの直し方」
再現:型ごとに、読める値・読めない値
| 型 | 読めた | 読めなかった(invalid input syntax) |
|---|---|---|
| integer | ' 12 '(前後の空白) |
''、'12'、'1,000'、'12.5'、'1e3'、'null' |
| numeric | — | '1,000'、'¥1000' |
| date | '2026/10/11'、'10/11/2026' |
'2026年10月11日'、'' |
| boolean | 'yes'・'on'・'1'・'t' |
'はい' |
| uuid | — | 'abc' |
txdemo=# select ''::int;
ERROR: invalid input syntax for type integer: ""
LINE 1: select ''::int;
^
文字列の 'null' も読めません。 値が無いことは、文字列ではなく SQL の NULL で表します。
数値の 12.5 と文字列の '12.5' で結果が違う
| 書き方 | 結果 |
|---|---|
'12.5'::int(文字列) |
エラー |
12.5::int(数値) |
13(四捨五入される) |
「10/11/2026」は設定で月日が入れ替わる
'10/11/2026'::date は、確認環境(DateStyle が ISO, MDY)では 2026-10-11、SET datestyle = 'ISO, DMY' にすると 2026-11-10 になりました。エラーにならずに日付が変わるので、スラッシュ区切りの日付は to_date で形式を指定して読むのが安全です。
多い原因1:空文字を数値の列に入れる
画面の入力欄が空のまま送られると、アプリからは空文字 '' が届きます。
cur.execute("INSERT INTO imp (id, price) VALUES (9, %s)", ("",))
# psycopg.errors.InvalidTextRepresentation: invalid input syntax for type integer: ""
cur.execute("INSERT INTO imp (id, price) VALUES (9, %s)", (None,)) # OK(NULL)
Python では None、Java では setNull() で NULL を渡します。 SQL の中で直すなら NULLIF です。
SELECT NULLIF('', '')::int; -- NULL(エラーにならない)
INSERT INTO imp (id, price) VALUES (9, NULLIF(:price, '')::int);
Java では別のエラーになる
ps.setString(1, "12"); // integer の列に setString
ERROR: column "price" is of type integer but expression is of type character varying (SQLSTATE 42804)
PostgreSQL JDBC で、数値の列に setString で値を渡すと、値が正しくても("12" でも)、型が違うというエラー(42804)になりました。数値は setInt・setLong・setBigDecimal、空なら setNull(1, Types.INTEGER) で渡します。
多い原因2:CSV の取り込み(COPY)
id,price,memo
1,100,a
2,,b ← 空(引用符なし)
3,"",c ← 空(引用符あり)
\copy imp FROM 'c5.csv' WITH (format csv, header)
ERROR: invalid input syntax for type integer: ""
CONTEXT: COPY imp, line 4, column price: ""
| CSV の値 | COPY(CSV 形式)での扱い |
|---|---|
,,(引用符なし・空) |
NULL |
,"",(引用符あり・空) |
空文字 → integer の列ではエラー |
CONTEXT に、何行目(line 4)のどの列(column price)かが出ます。エラーになると COPY 全体が取り消され、1行も入りませんでした(0 rows)。
Excel などで作った CSV は、空のセルを "" で書き出すことがあります。FORCE_NULL を付けると、引用符つきの空も NULL として読めました(PostgreSQL 公式ドキュメントの COPY の説明)。
\copy imp FROM 'c5.csv' WITH (format csv, header, force_null (price))
-- COPY 3(2 行目も 3 行目も price は NULL)
汚れたデータは、いったん文字列のまま取り込む
全角数字・カンマ・形式の違う日付が混ざる CSV は、すべて text の列の一時テーブルに取り込み、確かめてから変換します。PostgreSQL 16 では、pg_input_is_valid で、エラーを出さずに「その型として読めるか」を確かめられます。
CREATE TABLE stage (id text, price text, ordered text);
\copy stage FROM 'c6.csv' WITH (format csv, header)
-- 読めない行を一覧にする
SELECT id, price, ordered,
pg_input_is_valid(price, 'integer') AS price_ok,
pg_input_is_valid(ordered, 'date') AS date_ok
FROM stage
WHERE NOT pg_input_is_valid(coalesce(price, '0'), 'integer')
OR NOT pg_input_is_valid(ordered, 'date');
id | price | ordered | price_ok | date_ok
----+--------+----------------+----------+---------
2 | 1,000 | 2026/10/11 | f | t
3 | 120 | 2026年10月11日 | f | f
4 | | 2026-02-30 | | f ← 存在しない日付も見つかる
-- 直しながら変換する
SELECT id, NULLIF(replace(normalize(price, NFKC), ',', ''), '')::int AS price
FROM stage;
-- 1 | 100
-- 2 | 1000 ← カンマを外した
-- 3 | 120 ← 全角を半角に
-- 4 | NULL ← 空は NULL
エラーの内容まで知りたいときは pg_input_error_info です。
SELECT * FROM pg_input_error_info('1,000', 'integer');
-- invalid input syntax for type integer: "1,000" | | | 22P02
多い原因3:WHERE で文字列と比べている
SELECT * FROM imp WHERE price = '';
-- ERROR: invalid input syntax for type integer: ""
数値の列を空文字と比べても、エラーになります。 「値が無い行」を探すなら WHERE price IS NULL です。検索画面の条件が空のときに = '' を組み立てていないかを確かめます。
MySQL は、黙って 0 にすることがある
| 操作 | PostgreSQL | MySQL 8.0(strict モード) | MySQL(非 strict) |
|---|---|---|---|
integer の列に '' |
エラー(22P02) | エラー(1366) | 0 で保存(警告) |
integer の列に '1,000' |
エラー | エラー(1265) | 1 で保存(警告) |
CAST('1,000' AS ...) |
エラー | 1(警告のみ) | 1 |
'abc' = 0 |
エラー | 真(1) | 真(1) |
MySQL では、'1,000' が警告だけで 1 になり、'abc' = 0 が真になりました。 MySQL から移したアプリやデータで、PostgreSQL に変えたとたんにこのエラーが出るのは、MySQL が黙って変換していた値が、PostgreSQL ではエラーになるためです。データの誤りが表に出たと考え、上の方法で直します。
確認の手順(チェックリスト)
| 順番 | 確認すること | 方法 |
|---|---|---|
| 1 | 読めなかった値 | エラー文の最後の "..." |
| 2 | どの行・列か | COPY なら CONTEXT: ... line N, column 列名 |
| 3 | 空文字か | "" なら NULL にする(NULLIF、None、setNull、FORCE_NULL) |
| 4 | 全角・カンマ・形式 | normalize(..., NFKC)、replace、to_date |
| 5 | 汚れたデータの取り込み | text の一時テーブル+pg_input_is_valid |
| 6 | Java | 型に合った setInt などで渡す(setString は 42804) |
よくある質問
Q. SQLSTATE は何ですか。
A. 22P02(invalid_text_representation)です。psycopg では InvalidTextRepresentation の例外になります。
Q. 全角数字を自動で半角にして読めませんか。
A. 型の変換では読めません。normalize(値, NFKC) で半角にしてから変換します。確認環境では normalize('12', NFKC)::int が 12 になりました。
まとめ
- 文字列をその型として読めなかったエラー。エラー文の
"..."が読めなかった値 - いちばん多いのは空文字。NULL で渡す(
NULLIF・None・setNull) - CSV の
""は空文字、空欄は NULL。FORCE_NULLで両方 NULL に - 汚れたデータは text で取り込み、
pg_input_is_valid(PostgreSQL 16)で確かめてから変換 '10/11/2026'は DateStyle で月日が入れ替わる。to_dateで形式を指定する- MySQL は黙って 0 や 1 にすることがある。移行で表に出たデータの誤りを直す
参考・出典
確認日はいずれも 2026年10月11日です。
- PostgreSQL 16 Documentation「COPY」:https://www.postgresql.org/docs/16/sql-copy.html
- PostgreSQL 16 Documentation「System Information Functions and Operators」(pg_input_is_valid):https://www.postgresql.org/docs/16/functions-info.html
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「PostgreSQL invalid input syntaxの直し方」
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。