达梦数据库整数除法等运算默认舍弃小数
程序员文章站
2022-06-02 22:06:32
...
达梦数据库默认情况下,整数的除法运算处理与Oracle的处理稍有区别。达梦数据库中默认会舍弃小数,可以通过CALC_AS_DECIMAL参数进行控制。
现状描述
达梦数据库默认参数下,结果如下:
SQL> SELECT 123456/10000 FROM DUAL;
行号 123456/10000
---------- ------------
1 12
已用时间: 1.403(毫秒). 执行号:53.
SQL> SELECT ROUND(123456/10000,2) FROM DUAL;
行号 ROUND(123456/10000,2)
---------- ---------------------
1 12
已用时间: 0.770(毫秒). 执行号:55.
SQL> select round(12555/1000,0) from dual;
行号 ROUND(12555/1000,0)
---------- -------------------
1 12
已用时间: 0.596(毫秒). 执行号:59.
Oracle中:
SQL> SELECT 123456/10000 FROM DUAL;
123456/10000
------------
12.3456
SQL> SELECT ROUND(123456/10000,2) FROM DUAL;
ROUND(123456/10000,2)
---------------------
12.35
SQL> select round(12555/1000,0) from dual;
ROUND(12555/1000,0)
-------------------
13
可以观察到,默认情况下达梦数据库中,整数相除或者使用ROUND函数的结果小数位会直接舍弃,不会进行四舍五入,而Oracle中是会的。
在达梦数据库中使用小数类型进行测试:
SQL> select 12555.00/1000 from dual;
行号 12555./1000
---------- -----------
1 12.555
已用时间: 0.697(毫秒). 执行号:61.
SQL> select round(12555.00/1000,0) from dual;
行号 ROUND(12555./1000,0)
---------- --------------------
1 13
已用时间: 0.156(毫秒). 执行号:62.
SQL>
Oracle中:
SQL> select 12555.00/1000 from dual;
12555.00/1000
-------------
12.555
SQL> select round(12555.00/1000,0) from dual;
ROUND(12555.00/1000,0)
----------------------
13
可以观察到对于小数的运算,达梦数据库中执行结果与Oracle中两个的结果相同,那么可以猜测在达梦数据库中是否存在相关参数来控制整数的运算处理来与Oracle兼容。
原因
通过查找官方文档DBA手册,发现与CALC_AS_DECIMAL参数有关。该参数为静态参数,有3个取值:0,1,2,默认为0。各个值含义如下:
0:默认值,表示整数类型的除法、整数与字符或BINARY串的所有四则运算,结果都处理成整数;
1:表示整数类型的除法全部转换为DEC(0,0)处理;
2:表示将整数与字符或BINARY串的所有四则运算都转换为 DEC(0,0)处理
注:该参数只有在USE_PLN_POOL为0或1时有效。当USE_PLN_POOL为2或3时,按照CALC_AS_DECIMAL=2处理(USE_PLN_POOL默认为1)
根据实际需求进行调整,一般我们将该参数设置为1即可。
验证如下:
1、设置CALC_AS_DECIMAL参数值为1,并重启数据库生效
---查看
SQL> select para_name,para_value from v$dm_ini where para_name='CALC_AS_DECIMAL';
行号 PARA_NAME PARA_VALUE
---------- --------------- ----------
1 CALC_AS_DECIMAL 0
---修改
SQL> sp_set_para_value(2,'CALC_AS_DECIMAL',1);
DMSQL 过程已成功完成
已用时间: 23.465(毫秒). 执行号:63.
---重启数据库。
---查看
SQL> select para_name,para_value from v$dm_ini where para_name='CALC_AS_DECIMAL';
行号 PARA_NAME PARA_VALUE
---------- --------------- ----------
1 CALC_AS_DECIMAL 1
已用时间: 5.693(毫秒). 执行号:4.
2、执行上面的测试SQL
SQL> SELECT 123456/10000 FROM DUAL;
行号 123456/10000
---------- ------------
1 12.3456
已用时间: 0.466(毫秒). 执行号:6.
SQL> SELECT ROUND(123456/10000,2) FROM DUAL;
行号 ROUND(123456/10000,2)
---------- ---------------------
1 12.35
已用时间: 0.585(毫秒). 执行号:7.
SQL> select round(12555/1000,0) from dual;
行号 ROUND(12555/1000,0)
---------- -------------------
1 13
已用时间: 0.512(毫秒). 执行号:8.
可以观察到此时的SQL执行结果与Oracle中执行相同。
解决
修改CALC_AS_DECIMAL参数值为1,并重启数据库生效并验证。
Step1:sp_set_para_value(2,‘CALC_AS_DECIMAL’,1);
Step2:重启数据库
总结
达梦数据库默认情况下,整数的运算处理与Oracle的处理稍有区别。
对于与Oracle存在区别的地方,在达梦数据库中大部分都可以直接通过调整参数解决与Oracle的兼容性,这对于程序来说可以省掉部分的代码调整工作。
推荐阅读