While working with the str () function, I found that in some cases it bypasses the error, and the round () function works as expected. See an example:
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
Can anyone explain why this is happening?
EDIT1 : I tested various workarounds with the following base code:
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
Option 1 (original, in some cases erroneous):
str(@v, 18, 1)
Option 2 (slightly modified, but rounded correctly):
str(round(@v, 1), 18, 1)
Option 3 (double conversion and rounding):
convert(varchar(20), convert(decimal(18,1), round(@v, 1)))
Option 4 (double conversion only):
convert(varchar(20), convert(decimal(18,1), @v))
Results : Options 1 and 2 are about 2 times slower than the last two, but the result is justified. The fastest option is option 4.