SSRS与SQL使用ROUND函数结果不一致的原因及解决方法
SSRS与SQL ROUND计算结果不一致的原因及解决方案
核心原因
- 数值类型精度差异:如果SQL中
v_earnhrs和actl_hrly字段是DECIMAL/NUMERIC这类精确数值类型,乘法运算得到的是精确的329.6625;但SSRS表达式默认会把字段值转为Double双精度浮点数运算,浮点数的二进制存储特性会导致运算结果存在微小的精度误差,实际运算得到的可能是略大于329.665的数值,舍入后得到329.67。 - 舍入规则差异:SQL Server的
ROUND函数默认使用常规四舍五入规则,329.6625保留两位小数时,第三位小数为2,直接舍去得到329.66;而SSRS的Round函数基于VB runtime实现,默认使用银行家舍入法(四舍六入五成双),叠加浮点数精度误差的影响,就会出现和SQL计算结果不一致的情况。
对齐SQL结果的调整方案
方案1:计算逻辑迁移到SQL侧(最稳妥)
直接在数据集查询中完成乘法+舍入的全部计算,新增字段返回最终结果,SSRS直接调用该字段即可完全规避两端规则差异。
示例SQL代码:
SELECT *, ROUND(v_earnhrs * actl_hrly, 2) AS calc_result FROM 你的业务表
SSRS侧直接使用表达式:=Fields!calc_result.Value即可。
方案2:修改SSRS表达式适配SQL规则
如果必须在SSRS侧完成计算,先把字段值转为Decimal精确数值类型运算,再指定舍入模式为AwayFromZero(和SQL的四舍五入规则一致)。
示例表达式:
=Round(CDec(Fields!v_earnhrs.Value) * CDec(Fields!actl_hrly.Value), 2, System.MidpointRounding.AwayFromZero)
方案3:格式化对齐(仅适配展示场景)
如果只需要展示层面和SQL结果对齐,可直接使用格式化函数控制小数位数:
=FormatNumber(CDec(Fields!v_earnhrs.Value) * CDec(Fields!actl_hrly.Value), 2)
内容的提问来源于stack exchange,提问作者Loudrain
相关产品推荐
相关产品推荐

