挙動の確認
Oracle
SQL> create table test_tbl (num number);
表が作成されました。
SQL> insert into test_tbl values (12.34);
1行が作成されました。
SQL> select * from test_tbl;
NUM
----------
12.34
MySQL
mysql> create table test_tbl (num decimal);
Query OK, 0 rows affected (0.05 sec)
mysql> insert into test_tbl values (12.34);
Query OK, 1 row affected, 1 warning (0.03 sec)
mysql> select * from test_tbl;
+------+
| num |
+------+
| 12 |
+------+
1 row in set (0.00 sec)
PostgreSQL
mydb01=# create table test_tbl (num numeric);
CREATE TABLE
mydb01=# insert into test_tbl values (12.34);
INSERT 0 1
mydb01=# select * from test_tbl;
num
-------
12.34
(1 行)
SQL Server
1> create table test_tbl (num decimal);
2> insert into test_tbl values (12.34);
3> go
(1 rows affected)
1> select * from test_tbl;
2> go
num
--------------------
12
まとめ
精度・スケール指定なしのデータ型は、
- Oracle / PostgreSQL:小数点を保持する
- MySQL / SQL Server:小数点を丸める
どうせ Oracle だけ挙動が違うんだろと思っていたら、PostgreSQL も一緒だった。
PostgreSQL のドキュメントを見ると、SQL 標準では小数点を持たないことが仕様っぽい?
精度も位取りも指定せず、
NUMERIC
と記述すると、実装されている限界の精度まで、いかなる精度あるいは位取りの値も格納できる「制約の無い数値」列が作られます。 この類の列は入力値をいかなる特定の位取りにも変換しませんが、宣言された位取りを持つnumeric列は入力値をその位取りに変換します。 (標準SQLはデフォルトとして位取り0を要求していて、つまり、整数の精度に変換されます。 しかし、この方法はあまり役に立たないと思われます。 もし移植性を心配するなら、常に精度と位取りを明示的に設定してください。)