在使用str()函数时,我发现在某些情况下,round()舍入错误,而round()函数按预期工作.请看一下这个例子:
declare @v decimal(18,2) = 29.95
select str(@v, 18, 1)
--29.9
select round(@v, 1)
--30.00
set @v = 39.95
select str(@v, 18, 1)
--40.00
select round(@v, 1)
--40.00
Run Code Online (Sandbox Code Playgroud)
谁能解释为什么会这样?
EDIT1:我使用以下基本代码测试了不同的变通方法:
declare @v decimal(18,2) = 9.95
declare @r varchar(100)
declare @c int = 1000000
declare @ms int
declare @dt datetime2
set @dt = sysdatetime()
while @c > 0
begin
set @r = --different roundings
set @c = @c - 1
end
set @ms = DATEDIFF(ms, @dt, sysdatetime())
select @ms, @r
Run Code Online (Sandbox Code Playgroud)
选项1(原始的,在某些情况下错误地轮回):
str(@v, 18, 1)
Run Code Online (Sandbox Code Playgroud)
选项2(略有修改但正确舍入):
str(round(@v, 1), 18, 1)
Run Code Online (Sandbox Code Playgroud)
选项3(双转换和舍入):
convert(varchar(20), convert(decimal(18,1), round(@v, 1)))
Run Code Online (Sandbox Code Playgroud)
选项4(仅双转换):
convert(varchar(20), convert(decimal(18,1), @v))
Run Code Online (Sandbox Code Playgroud)
结果:选项1和2大约比最后两个慢2倍,但结果是右对齐的.选项4最快.
str()的参数是浮点数,因此您的十进制值会隐式转换为 float(53),然后再转换为字符串。因此您会看到浮点舍入错误。
对查询进行轻微修改,您可以看到实际执行计划中发生了什么。
declare @v decimal(18,2) = 29.95
select top(1) str(@v, 18, 1)
Run Code Online (Sandbox Code Playgroud)
declare @v decimal(18,2) = 29.95
select top(1) str(@v, 18, 1)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1074 次 |
| 最近记录: |