探究达梦CALC_AS_DECIMAL参数
1.背景
达梦数据库中的CALC_AS_DECIMAL参数用于控制特定算术运算(如整数除法或整数与可转换为数字的字符串/二进制数据的运算)的结果数据类型,主要解决用户在这些场景下可能遇到的计算结果与预期不符的问题。例如,当用户期望除法运算返回带小数的结果时,数据库默认可能仅返回整数,而通过设置此参数,可以强制使运算结果保留小数精度(如DECIMAL类型),从而确保计算准确性。然而,若该参数的设置与业务所需的计算精度要求不匹配,可能会导致计算结果偏离预期,例如丢失关键的小数部分,进而影响后续业务处理或数据分析的正确性。
2.参数简介
2.1.CALC_AS_DECIMAL
CALC_AS_DECIMAL
静态参数 0:默认值,表示整数类型的除法、整数与字符或 BINARY 串的所有四则运算,结果都处理成整数;
1:表示整数类型的除法全部转换为DEC(0,0)处理;
2:表示将整数与字符或BINARY串的所有四则运算都转换为 DEC(0,0)处理;
3:所有涉及整型的四则运算全部转换为DEC(0,0)处理;
2.2.USE_PLN_POOL
该参数的有效性受到USE_PLN_POOL参数的影响。当USE_PLN_POOL的值为0或1时,CALC_AS_DECIMAL有效。当USE_PLN_POOL为2或3时,CALC_AS_DECIMAL的行为将按照其取值为2的情况处理。
USE_PLN_POOL
是否重用执行计划
静态参数 0:禁用执行计划的重用。每条SQL语句在每次执行时都会生成一个新的执行计划。
1:启用基本的执行计划重用功能。数据库会为已执行过的、完全相同的SQL文本尝试重用已缓存的执行计划。这是默认设置。
2:启用执行计划重用,并对不包含显式绑定参数的语句进行常量参数化优化。例如,像SELECT * FROM T WHERE C=10和SELECT * FROM T WHERE C=20这样的查询,如果它们结构相同只是常量值不同,数据库可能会将常量值进行参数化处理,生成一个参数化的计划(如SELECT * FROM T WHERE C=?),提高计划的重用率。简单来说,只对那些直接写死常量值的简单情况进行参数化。
3:启用执行计划重用,采取更积极的常量参数化策略。即使对于包含显式绑定参数的语句,或者结构上看起来不太容易参数化的语句,系统也可能会尝试进行常量参数化优化,进一步提高计划重用率。简单来说,在处理设置2的基础上会分析更多可参数化的点。
2.3.DEC(P, S)概述
DEC是DECIMAL数据类型的缩写。例如dec(3,1)指的就是这整个数字只有3位,但小数点后只有1位,例如12.5、65.2这些数字。而CALC_AS_DECIMAL参数中DEC(0,0)并不是说它的刻度和精度都是0,而是启用DECIMAL的高精度运算模式。最终的刻度和精度是根据运算的数值和规则动态确定的,而不是固定为DEC(0,0)。
3.测试CALC_AS_DECIMAL不同取值的效果
3.1.创建测试数据
CREATE TABLE test (
C1 INT, – 整数列
C2 INT, – 另一个整数列,用于纯整数运算
C3 VARCHAR(10), – 字符型数字列 (可转换为整数或小数)
C4 BINARY(4) – BINARY 列 (表示整数)
);
– 插入测试数据
INSERT INTO test (C1, C2, C3, C4) VALUES (10, 3, ‘5’, 0x00000002);
INSERT INTO test (C1, C2, C3, C4) VALUES (7, 2, ‘3’, 0x00000003);
INSERT INTO test (C1, C2, C3, C4) VALUES (8, 4, ‘2.5’, 0x00000004);
INSERT INTO test (C1, C2, C3, C4) VALUES (9, 3, ‘3.0’, 0x00000002);
COMMIT;
– 查看插入的数据
SELECT * FROM test;
3.2.执行测试查询语句
-纯整数计算
SELECT
C1, C2,
C1 / C2 AS 整数_除以_整数,
C1 + C2 AS 整数_加_整数,
C1 - C2 AS 整数_减_整数,
C1 * C2 AS 整数_乘以_整数
FROM test;
–整数与字符计算
SELECT
C1, C3,
C1 / C3 AS 整数_除以_字符,
C1 + C3 AS 整数_加_字符,
C1 - C3 AS 整数_减_字符,
C1 * C3 AS 整数_乘以_字符
FROM test;
–整数与 BINARY计算
SELECT
C1, C4,
C1 / C4 AS 整数_除以_二进制,
C1 + C4 AS 整数_加_二进制,
C1 - C4 AS 整数_减_二进制,
C1 * C4 AS 整数_乘以_二进制
FROM test;
3.3.调整参数
sp_set_para_value(2,‘CALC_AS_DECIMAL’,0);
–重启数据库后检查
select PARA_NAME,PARA_VALUE from v$dm_ini where para_name LIKE ‘CALC_AS_DECIMAL’;
3.4.CALC_AS_DECIMAL = 0
表示整数类型的除法、整数与字符或 BINARY 串的所有四则运算,结果都处理成整数。
结论:纯整数运算:除法会截掉后面的小数点取整数。加减乘则按照既定规则运算
结论:整数与字符型数字运算:因为C3列为字符类型,会自动按照四舍五入的方式转换为整数类型。例如 8+’2.5’ 会转换为 8+3,结果为11,符合测试结果
结论:整数与BINARY运算:会将C4列十六进制转换为十进制进行运算,除法会截掉小数点。
3.5.CALC_AS_DECIMAL = 1
表示整数类型的除法全部转换为DEC(0,0)处理
结论:纯整数运算:除法会保留后面的小数点。加减乘则按照既定规则运算;
结论:整数与字符型数字运算:因为C3列为字符类型,会自动按照四舍五入的方式转换为整数类型。例如 8+’2.5’ 会转换为 8+3,结果为11,符合测试结果;但是,针对除法8/2.5,因为参数CALC_AS_DECIMAL=1是只作用于除法运算的,当进行8/2.5时,首先将2.5转换为数值类型的2.5,此时启用DECIMAL进行高精度运算,保留小数点从而不进行四舍五入,最后的结果为8/2.5=3.2,符合测试结果
结论:整数与BINARY运算:会将C4列十六进制转换为十进制进行运算,除法会保留小数点。
3.6.CALC_AS_DECIMAL = 2
表示将整数与字符或BINARY串的所有四则运算都转换为DEC(0,0)处理。
结论:纯整数运算:除法会保留后面的小数点。加减乘则按照既定规则运算
结论:整数与字符型数字运算:因为参数CALC_AS_DECIMAL=2是作用于所有的四则运算的,即保留小数点进行运算。当进行8/2.5时,首先将2.5转换为数值类型的2.5,此时启用DECIMAL进行高精度运算,保留小数点从而不进行四舍五入,最后的结果为8/2.5=3.2。当8+2.5时,也会保留小数点进行运算,结果为10.5,符合测试结果
结论:整数与BINARY运算:会将C4列十六进制转换为十进制进行运算,除法会保留小数点
3.7.CALC_AS_DECIMAL = 3
结论:当配置为3时,所有数值都遵循DECIMAL的规则。相较于CALC_AS_DECIMAL= 2,参数3的差异在于纯整数加减乘的结果类型从INTEGER变为NUMBER,其他已为NUMBER 的运算类型保持不变。
值为2时:
值为3时:
文章
阅读量
获赞