达梦数据库中的CALC_AS_DECIMAL
参数用于控制某些特定算术运算(特别是整数之间的除法,以及整数与可转换为数字的字符串/二进制数据进行的运算)的结果数据类型。它主要解决了用户在这些场景下可能遇到的计算结果与预期不符的问题,例如期望得到带小数的除法结果,但数据库默认却返回了整数。通过设置此参数,用户可以选择让这些运算强制产生具有小数精度的结果类型(如DECIMAL
),以确保计算的准确性。如果此参数的设置与业务对计算结果所需精度的要求不符,就可能导致计算结果偏离预期,比如丢失重要的小数部分,从而影响基于这些计算结果的后续业务处理或数据分析的正确性。
CALC_AS_DECIMAL 参数 (静态参数)
值 | 描述 |
---|---|
0 |
默认值,表示整数类型的除法、整数与字符或 BINARY 串的所有四则运算,结果都处理成整数; |
1 |
表示整数类型的除法全部转换为 DEC(0,0) 处理; |
2 |
表示将整数与字符或 BINARY 串的所有四则运算都转换为 DEC(0,0) 处理; |
3 |
所有涉及整型的四则运算全部转换为 DEC(0,0) 处理; |
简单来说,假设你有两个整数,10和3,计算10/3:
同样,如果你用一个整数比如10去加一个字符串 ‘5’:
该参数的有效性受到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的基础上会分析更多可参数化的点。 |
DEC是DECIMAL数据类型的缩写。例如dec(3,1)指的就是这整个数字只有3位,但小数点后只有1位,例如12.5、65.2这些数字。而CALC_AS_DECIMAL参数中DEC(0,0)并不是说它的刻度和精度都是0,而是启用DECIMAL的高精度运算模式。最终的刻度和精度是根据运算的数值和规则动态确定的,而不是固定为DEC(0,0)。
-- 创建测试表
CREATE TABLE comprehensive_test (
C1 INT, -- 整数列
C2 INT, -- 另一个整数列,用于纯整数运算
C3 VARCHAR(10), -- 字符型数字列 (可转换为整数或小数)
C4 BINARY(4) -- BINARY 列 (表示整数)
);
-- 插入测试数据
INSERT INTO comprehensive_test (C1, C2, C3, C4) VALUES (10, 3, '5', 0x00000002);
INSERT INTO comprehensive_test (C1, C2, C3, C4) VALUES (7, 2, '3', 0x00000003);
INSERT INTO comprehensive_test (C1, C2, C3, C4) VALUES (8, 4, '2.5', 0x00000004);
INSERT INTO comprehensive_test (C1, C2, C3, C4) VALUES (9, 3, '3.0', 0x00000002);
COMMIT;
-- 查看插入的数据
SELECT * FROM comprehensive_test;
--纯整数计算
SELECT
C1, C2,
C1 / C2 AS 整数_除以_整数,
C1 + C2 AS 整数_加_整数,
C1 - C2 AS 整数_减_整数,
C1 * C2 AS 整数_乘以_整数
FROM comprehensive_test;
--整数与字符计算
SELECT
C1, C3,
C1 / C3 AS 整数_除以_字符,
C1 + C3 AS 整数_加_字符,
C1 - C3 AS 整数_减_字符,
C1 * C3 AS 整数_乘以_字符
FROM comprehensive_test;
--整数与 BINARY计算
SELECT
C1, C4,
C1 / C4 AS 整数_除以_二进制,
C1 + C4 AS 整数_加_二进制,
C1 - C4 AS 整数_减_二进制,
C1 * C4 AS 整数_乘以_二进制
FROM comprehensive_test;
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';
表示整数类型的除法、整数与字符或 BINARY 串的所有四则运算,结果都处理成整数。
表示整数类型的除法全部转换为DEC(0,0)处理。
总结:相对于CALC_AS_DECIMAL= 0,参数1改变了除法运算的行为,无论是纯整数除法还是整数与BINARY的除法,结果都从INTEGER截断变为了DECIMAL保留小数点。而整数与字符型数字的运算,以及纯整数或BINARY加减乘运算,与参数0保持一致。
表示将整数与字符或BINARY串的所有四则运算都转换为DEC(0,0)处理。
总结:相对于CALC_AS_DECIMAL= 1,参数2在整数与BINARY的加减乘运算上存在差异:结果类型从INTEGER变为了DECIMAL(38,0)。其他运算类型(纯整数运算、整数与字符运算、整数与BINARY除法)的结果类型和计算结果与参数1保持一致。
所有涉及整型的四则运算全部转换为DEC(0,0)处理。
总结:当配置为3时,所有数值都遵循DECIMAL的规则。相较于CALC_AS_DECIMAL= 2,参数3的差异在于纯整数加减乘的结果类型从INTEGER变为DECIMAL(38,0),其他已为DECIMAL(38,0) 的运算类型保持不变。
数据库尝试将字符值’ABC’强制转换为数字类型以执行加法运算,但’ABC’ 不是一个有效的数字表示,因此转换失败导致计算终止报错。
--数据插入
INSERT INTO test_calc (c1, c2, c3, c4) VALUES (5, 2, 'TEST', 'ABC');
commit;
--执行计算
SELECT c1 + c4 FROM test_calc WHERE c4 = 'ABC';
文章
阅读量
获赞