Oracle table 中的数字列存储 'hidden' 个小数位
Number column in Oracle table storing 'hidden' decimal places
第一次在这里提问,因为搜索这些术语太模糊了。我不知道数据是如何进入 table 的(我想只是通过 "insert into tomtest(test) values (280.1);" 但不能确定)但是这个例子看起来很奇怪。为什么直行select显示小数点后1位,而to_charselect显示小数点后14位?
SQL> set linesize 100
SQL> select banner from v$version;
BANNER
--------------------------------------------------------------------------------
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
PL/SQL Release 12.2.0.1.0 - Production
CORE 12.2.0.1.0 Production
TNS for Linux: Version 12.2.0.1.0 - Production
NLSRTL Version 12.2.0.1.0 - Production
SQL> describe tomtest
Name Null? Type
----------------------------------------------------- -------- ------------------------------------
TEST NUMBER
SQL> select * from tomtest;
TEST
----------
280.1
SQL> select * from tomtest where test = 280.1;
no rows selected
SQL> select to_char(test) from tomtest;
TO_CHAR(TEST)
----------------------------------------
280.10000000000002
SQL> SELECT data_type, data_length, data_precision, data_scale FROM USER_TAB_COLS WHERE TABLE_NAME = 'TOMTEST' AND COLUMN_NAME = 'TEST';
DATA_TYPE DATA_LENGTH DATA_PRECISION DATA_SCALE
NUMBER 22
原因是sql加上默认的数字格式。
在数据库中你有值 280.10000000000002
而不是 280.1
这里有一个例子
SQL> select 128.000000000000000000006 as test from dual;
test
-------------------------
128
SQL> select 128.200000000000000000006 as test from dual;
test
-------------------------
128,2
您可以更改数字格式并再次检查
SQL> SET NUMF 999999999.99999999999999999999999999999999
SQL> select 128.200000000000000000006 as test from dual;
test
-------------------------------------------
128.20000000000000000000600000000000
SQL>
更新:
这种现象可以解释为你的数据类型只是定义为数字,没有精确的精度规范。
这意味着您可以保存一个小数,但不要给出小数位的确切规范。
这是一个显示差异的示例。
CREATE TABLE test_num(
n1 NUMBER,
n2 NUMBER(23,15));
INSERT INTO test_num VALUES(208.20000000000006,208.20000000000006);
SELECT t.*FROM test_num t;
结果在 PLSQL/Developer:
N N2
--- ---
208,2 208,200000000000030
in plsql 开发者可以将数字显示为字符。如果你想激活首选项中的复选框:Tools -> Preferences -> SQL Window -> Number fields to_char
在你的情况下,我会在 insert/update 上将一个数值四舍五入到一定的小数位,或者将你的数据类型从 number
更改为 number(p, s)
(其中 p 是精度,s 是比例。)
第一次在这里提问,因为搜索这些术语太模糊了。我不知道数据是如何进入 table 的(我想只是通过 "insert into tomtest(test) values (280.1);" 但不能确定)但是这个例子看起来很奇怪。为什么直行select显示小数点后1位,而to_charselect显示小数点后14位?
SQL> set linesize 100
SQL> select banner from v$version;
BANNER
--------------------------------------------------------------------------------
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
PL/SQL Release 12.2.0.1.0 - Production
CORE 12.2.0.1.0 Production
TNS for Linux: Version 12.2.0.1.0 - Production
NLSRTL Version 12.2.0.1.0 - Production
SQL> describe tomtest
Name Null? Type
----------------------------------------------------- -------- ------------------------------------
TEST NUMBER
SQL> select * from tomtest;
TEST
----------
280.1
SQL> select * from tomtest where test = 280.1;
no rows selected
SQL> select to_char(test) from tomtest;
TO_CHAR(TEST)
----------------------------------------
280.10000000000002
SQL> SELECT data_type, data_length, data_precision, data_scale FROM USER_TAB_COLS WHERE TABLE_NAME = 'TOMTEST' AND COLUMN_NAME = 'TEST';
DATA_TYPE DATA_LENGTH DATA_PRECISION DATA_SCALE
NUMBER 22
原因是sql加上默认的数字格式。
在数据库中你有值 280.10000000000002
而不是 280.1
这里有一个例子
SQL> select 128.000000000000000000006 as test from dual;
test
-------------------------
128
SQL> select 128.200000000000000000006 as test from dual;
test
-------------------------
128,2
您可以更改数字格式并再次检查
SQL> SET NUMF 999999999.99999999999999999999999999999999
SQL> select 128.200000000000000000006 as test from dual;
test
-------------------------------------------
128.20000000000000000000600000000000
SQL>
更新: 这种现象可以解释为你的数据类型只是定义为数字,没有精确的精度规范。 这意味着您可以保存一个小数,但不要给出小数位的确切规范。
这是一个显示差异的示例。
CREATE TABLE test_num(
n1 NUMBER,
n2 NUMBER(23,15));
INSERT INTO test_num VALUES(208.20000000000006,208.20000000000006);
SELECT t.*FROM test_num t;
结果在 PLSQL/Developer:
N N2
--- ---
208,2 208,200000000000030
in plsql 开发者可以将数字显示为字符。如果你想激活首选项中的复选框:Tools -> Preferences -> SQL Window -> Number fields to_char
在你的情况下,我会在 insert/update 上将一个数值四舍五入到一定的小数位,或者将你的数据类型从 number
更改为 number(p, s)
(其中 p 是精度,s 是比例。)