我正在尝试编写一个存储过程,并且我得到意外的除以0异常。
我已将其缩小到以下示例。
为什么世界会这样做:
declare @A decimal;
declare @B decimal;
declare @C decimal;
set @A = 4;
set @B = 9;
set @C = @A/@B
select @A/@B as 'Expected'
select @C as 'Wut'
导致这个?
Expected
---------------------------------------
0.4444444444444444444
(1 row(s) affected)
Wut
---------------------------------------
0
(1 row(s) affected)
答案 0 :(得分:10)
问题是您没有为decimal
类型指定比例。来自MSDN:
s(比例)
将存储在小数点右侧的小数位数。从p中减去此数字以确定小数点左侧的最大位数。比例必须是从0到p的值。只有在指定精度时才能指定比例。 默认比例为0 ;因此,0 <= s <= p。
因此,当您尝试将@A/@B
存储回@C
时,小数部分会被截断。
注意:
declare @A decimal(18, 3);
declare @B decimal(18, 3);
declare @C decimal(18, 3);
set @A = 4;
set @B = 9;
set @C = @A/@B
select @A/@B -- 0.44444444444444444444
select @C -- 0.444
答案 1 :(得分:0)
这种情况正在发生,因为如果您没有声明精确度和比例,则十进制小数点左侧的(18, 0)
18位数字会向右移动,而右侧则为0。
如果您将C更改为如此定义:
declare @A decimal;
declare @B decimal;
declare @C decimal (18, 9);
set @A = 4;
set @B = 9;
set @C = @A/@B
select @A/@B as 'Expected'
select @C as 'Wut'
你应该得到一个正确的答案
Expected
---------------------------------------
0.4444444444444444444
(1 row(s) affected)
Wut
---------------------------------------
0.444444444
(1 row(s) affected)