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 是比例。)