2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

"Out of range value for column 'カラム名' at 行番号" に対処した

Last updated at Posted at 2021-02-05

開発業者が納品したWebアプリケーションがエラーを吐いていた。
致命的な問題で無かったことから発覚が遅れ、瑕疵担保責任を追及できる期間はとうに過ぎていたので、自分で直したという話。

調査ついでにエラーログの見方を簡単に説明しよう。

出力されたエラーメッセージ

_mysql_exceptions.DataError: (1264, "Out of range value for column 'カラム名' at row 1")

MySQLdbというPythonのモジュールが投げた例外のようだ。
最初の 1264 は4桁なので、MySQL独自のエラーコードだろう。

2つのエラー番号

MySQLのエラー番号には、

  1. MySQL独自のエラーコード(4桁)
  2. ODBCやANSI SQLで定められたSQLSTATE(5桁)

がある。

SQLSTATEは汎化されているので、MySQLに特化した独自コードの方が詳細に特定できる。
公式サイトですべてのエラーメッセージを確認できるが、特に良く見かけるものを以下に抜粋する。

Row 行番号 doesn't contain data for all columns

  • エラーコード:1261
  • SQLSTATE:01000
  • 意味:すべてのカラムへのデータを含んでいない

Row 行番号 was truncated; it contained more data than there were input columns

  • エラーコード:1262
  • SQLSTATE:01000
  • 意味:カラムよりも多いデータを含んでいたので、切り捨てたデータがある

Column set to default value; NULL supplied to NOT NULL column 'カラム名' at row 行番号

  • エラーコード:1263
  • SQLSTATE:22004
  • 意味:NOT NULL のカラムにデフォルト値の NULL を登録した

Out of range value for column 'カラム名' at row 行番号

  • エラーコード:1264
  • SQLSTATE:22003
  • 意味:範囲外の値だったので、取り敢えず限界の値で登録した

▶ 今回出力されたエラーメッセージである。

Data truncated for column 'カラム名' at row 行番号

  • エラーコード:1265
  • SQLSTATE:01000
  • 意味:先頭からみて入れられるところまで登録し、残りは切り捨てた

つまり…

エラーコード 1264 は、データ型の範囲を超えた値をINSERTしたときに発生するWarningである。直前に実行したSQLのWarningは SHOW WARNINGS で確認できる。
データ型の範囲を超えると、そのデータ型の最大値または最小値に調整されて登録されるはずだが、PythonがDataError例外を投げたのでrollbackされたと推測。実際にも登録されていなかった。

スタックトレース例
insert into zzzzz_table values(5,1611728121,0,162,58.2,63.9,1,27.5)

Traceback (most recent call last):
  File "/foo/bar/example.py", line 547, in <module>
    fooList()
  File "/foo/bar/example.py", line 164, in barList
    cursor.execute(qstr)
  File "/usr/lib/python2.7/dist-packages/MySQLdb/cursors.py", line 226, in execute
    self.errorhandler(self, exc, value)
  File "/usr/lib/python2.7/dist-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
    raise errorvalue
_mysql_exceptions.DataError: (1264, "Out of range value for column 'xxxxx' at row 1")

データ型

対象カラムのデータ型をDESCで確認するとTINYINTであった。
TINYINTの取りうる範囲は次の通り。

  • バイト数: 1バイト
  • デフォルト桁数: tinyint(4)
  • 符号付き(SIGNED)の範囲:-128 ~ 127

データ型の後にUNSIGNEDを付けると符号なしとなり、0~255の範囲になる。
ちなみに tinyint(1) はBoolean型と同じだ。

直前のSQLで127を超える値をINSERTしていたが、運用上ありえない値なのでソースコードを修正した。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?