ネットの海の片隅で

技術ネタの放流、あるいは不法投棄。

PostgreSQLのDecimal/Numeric型の挙動

公式情報はこのあたり。

PostgreSQL 任意の精度を持つ数

実行環境

データベース・テーブルの作成

psql (9.3.5)

postgres=# create database decimal_test;
CREATE DATABASE

postgres=# \c decimal_test

decimal_test=# CREATE TABLE decimals(num decimal(5,1) NOT NULL);
CREATE TABLE

decimal_test=# \d decimals
      Table "public.decimals"
 Column |     Type     | Modifiers
--------+--------------+-----------
 num    | numeric(5,1) | not null

decimal(5,1)すなわち、全部で5桁、小数部分が1桁の小数として作成。

INSERTしてみる

まずは普通に

decimal_test=# INSERT INTO decimals (num) VALUES (1234.5);
  num
--------
 1234.5
(1 row)
decimal_test=# INSERT INTO decimals (num) VALUES (12.3);
  num
--------
 1234.5
   12.3
(2 rows)

小数部分の桁数を指定より多く

decimal_test=# INSERT INTO decimals (num) VALUES (12.34);
  num
--------
 1234.5
   12.3
   12.3
(3 rows)
decimal_test=# INSERT INTO decimals (num) VALUES (12.35);
  num
--------
 1234.5
   12.3
   12.3
   12.4
(4 rows)

指定した小数部分の桁数に丸められた上でINSERTされる。

整数部分の桁数を指定より多く

decimal_test=# INSERT INTO decimals (num) VALUES (12345.6);
ERROR:  numeric field overflow
DETAIL:  A field with precision 5, scale 1 must round to an absolute value less than 10^4.

エラーを吐かれる。

その他

decimal_test=# INSERT INTO decimals (num) VALUES (-1234.5);
   num
---------
  1234.5
    12.3
    12.3
    12.4
 -1234.5
(5 rows)

もちろん負数も可。

decimal_test=# INSERT INTO decimals (num) VALUES (1);
   num
---------
  1234.5
    12.3
    12.3
    12.4
 -1234.5
     1.0
(6 rows)

小数部分は0埋めされる。*1

*1:ただし、物理的には0埋めされていないらしい。