我真的希望有一些SQL专家可以帮助您解决这个问题(如果以前已经回答过,请向我道歉。我确实尝试过找到类似的帖子,但无济于事):
declare @theanswer numeric(38,16) select @theanswer = 0.01 / 0.0074464347 select @theanswer
以上结果为1.3429245542165000
但是以下内容(对我来说看起来一样)
declare @val1 numeric(38,16); declare @val2 numeric(38,16); set @val1 = 0.01; set @val2 = 0.0074464347; select @val1/@val2
结果与1.342924并被截断了吗?
有任何想法吗?
为了获得结果的真实精度和小数位数(@ val1 / @ val2),我将执行此T-SQL脚本
T-SQL
DECLARE @val1 NUMERIC(38,16); DECLARE @val2 NUMERIC(38,16); SET @val1 = 0.01; SET @val2 = 0.0074464347; SELECT @val1/@val2 ,SQL_VARIANT_PROPERTY(@val1/@val2, 'BaseType') [BaseType] ,SQL_VARIANT_PROPERTY(@val1/@val2, 'Precision') [Precision] ,SQL_VARIANT_PROPERTY(@val1/@val2, 'Scale') [Scale]
结果将是:
(No column name) BaseType Precision Scale 1.342924 numeric 38 6
因此,结果精度为38,结果小数位数为6。MSDN提供了一些有关算术运算的精度和小数位数的详细信息。这些信息可以在这里找到:精度,小数位和长度(Transact- SQL):
Operation = e1 / e2 Result precision = p1 - s1 + s2 + max(6, s1 + p2 + 1) Result scale * = max(6, s1 + p2 + 1)
使用这些公式,我们可以编写下一个T-SQL脚本来获得理论精度和结果的缩放比例(@ val1 / @ val2):
SELECT @p1 = 38 --or CONVERT(INT, SQL_VARIANT_PROPERTY(@val1, 'Precision')) ,@s1 = 16 --or CONVERT(INT, SQL_VARIANT_PROPERTY(@val1, 'Scale')) ,@p2 = 38 --or CONVERT(INT, SQL_VARIANT_PROPERTY(@val2, 'Precision')) ,@s2 = 16 --or CONVERT(INT, SQL_VARIANT_PROPERTY(@val2, 'Scale')); --SELECT @p1 [@p1], @s1 [@s1], @p2 [@p2], @s2 [@s2]; SELECT @p_result = @p1 - @s1 + @s2 + CASE WHEN 6 >= @s1 + @p2 + 1 THEN 6 WHEN 6 < @s1 + @p2 + 1 THEN @s1 + @p2 + 1 END ,@s_result = CASE WHEN 6 >= @s1 + @p2 + 1 THEN 6 WHEN 6 < @s1 + @p2 + 1 THEN @s1 + @p2 + 1 END; SELECT @p_result [@p_result], @s_result [@s_result];
结果是:
@p_result @s_result 93 55
因此,对于此算术运算(@ val1 / @ val2),theory精度和小数位数为93和,55而实际精度和小数位数为38和6。实际精度为38,因为 “ 结果精度 和小数 位数的绝对最大值为38 ”。
theory
93
55
38
6
关于实际结果量表(6)MSDN,尚不清楚: “当结果精度大于38时, 将减小相应的量表 以防止结果的整数部分被截断”。
为了查看“相应的比例是如何减小”的,我使用NUMERIC具有相同比例(16)但不同比例(从16到38)的值执行了上述测试(脚本1表示实际精度和比例,脚本2表示理论精度和比例) 。这些测试的结果是:
NUMERIC
/* Result prec. Result scale (T=theoretical value, R=real value) T-R T-R --@val1 and @val2 data type 49-38 33-22 --NUMERIC(16, 16) 51-38 34-21 --NUMERIC(17, 16) 53-38 35-20 --NUMERIC(18, 16) 55-38 36-19 --NUMERIC(19, 16) ... 61-38 39-16 --NUMERIC(22, 16) -- <-- data type for [real] result scale 16 ... 77-38 47-8 --NUMERIC(30, 16) 79-38 48-7 --NUMERIC(31, 16) 81-38 49-6 --NUMERIC(32, 16) 83-38 50-6 --NUMERIC(33, 16) 85-38 51-6 --NUMERIC(34, 16) ... 93-38 55-6 --NUMERIC(38, 16) */
检查这些结果:
1.我看到了实际结果量表的算术级数:从22到6,步骤-1。
2.此外,如果@ val1和@ val2的小数位是常数(NUMERIC(...,16)),则@ val1和@ val2精度(从16到32)与[实际]结果小数位(从16到6)之间存在反相关。
NUMERIC(...,16)
3.如果@ val1和@ val2的精度为32或更高(NUMERIC(32->38,16)),则[真实]结果比例始终为6 =>这是您的情况。
NUMERIC(32->38,16)
4.如果需要更大的[真实]结果量表(超过6),则需要对@ val1和@ val2:使用较低的精度NUMERIC(22, 16):
NUMERIC(22, 16)
SELECT CONVERT(NUMERIC(22,16),@val1) / CONVERT(NUMERIC(22,16),@val2) [CONVERT(NUMERIC(22,16)] ,SQL_VARIANT_PROPERTY( CONVERT(NUMERIC(22,16),@val1) / CONVERT(NUMERIC(22,16),@val2) , 'BaseType') [BaseType] ,SQL_VARIANT_PROPERTY( CONVERT(NUMERIC(22,16),@val1) / CONVERT(NUMERIC(22,16),@val2) , 'Precision') [Precision] ,SQL_VARIANT_PROPERTY( CONVERT(NUMERIC(22,16),@val1) / CONVERT(NUMERIC(22,16),@val2) , 'Scale') [Scale] CONVERT(NUMERIC(22,16) BaseType Precision Scale ---------------------- -------- --------- ----- 1.3429245542165299 numeric 38 16