2009-09-25 41 views
1

我发现了一些奇怪的行为,存储过程以一两分钱返回不准确的结果。此SQL代码是否容易出现舍入错误?

下面的代码(我没有写):

ALTER PROCEDURE [dbo].[TN_GetSimpleBalance] 
    @custID int, 
    @nBalance decimal (8,2) output 
AS 

declare @ArBalance as decimal (8,2) 
declare @custStatusCode varchar (2) 
declare @unbilledCallsAmount as decimal (8,2) 

set @nBalance = 0 

set @ArBalance = 0 
set @custstatusCode = '' 
set @unbilledCallsAmount = 0 


SET NOCOUNT ON 

    select @unbilledCallsAmount = isnull(sum(callcharge+taxamount),0) 
    from call with (NOLOCK) where custid = @custID and callstatuscode in ('R', 'B') 

    --get AR balance 
    select @ArBalance = isnull(sum(amount),0) 
    from artran with (NOLOCK) 
    where custid = @custID AND POSTEDFLAG ='Y' 

    set @nBalance = @unbilledCallsAmount + @ArBalance 

@nBalance被显示为零,即使另一个应用是告诉我的客户已经$ .02。 callchargetaxamount都是货币数据类型。

这是我第一次遇到这样的情况,但我把一些相关的代码来生产,已经被“请”来研究这个。

你有什么需要?货币和小数数据类型之间有没有奇怪的地方?你认为还有什么可以解释这一点?

+0

@nBalance在哪里申报? – Shawn 2009-09-25 18:33:52

+0

编辑添加声明:) – 2009-09-25 18:34:57

+0

我不知道的唯一的东西是金额数据类型。你可以尝试转换的钱字段小数8,2,如果结果改变 – Shawn 2009-09-25 18:37:48

回答

0

哪些数据类型是callchargetaxamount?我会按照该数据类型进行所有计算,并在最后转换为十进制。目前所有的中间变量都是小数,这意味着舍入错误复合。直到最后都不要轮回。

+0

callcharge和TAXAMOUNT都是钱数据类型。 – 2009-09-25 18:46:50

1

我没有看到你的代码中的任何数据类型的钱,但我相信call.callcharge & call.taxamount的?我不知道关于精确度问题。

也许你能做的最好的事情就是试图找到其中的数据具有这种差异具体的测试情况,看看你是否能始终如一地重现。然后,您可以一次挑选一个逻辑语句并找出导致差异的位置。

是否有可能你有一个null callcharge或零taxamount? (null +( - $ 0.02))=> null;也许

isnull(sum(callcharge+taxamount),0) 

应该是:

sum(isnull(callcharge, 0)+isnull(taxamount,0)) 

@unbilledCallsAmount或@ArBalance也可能为空,如果这些select语句返回任何记录。 HTH,

0

使用这个时候,和值尝试不同的硬编码值callcharge & TAXAMOUNT:

declare @DecimalAmount as decimal (8,2) 
declare @MoneyAmount as money 

select @DecimalAmount = isnull(sum(callcharge+taxamount),0) 
     ,@MoneyAmount = isnull(sum(callcharge+taxamount),0) 
    from (select CONVERT(money,1.43) AS callcharge, CONVERT(money,.83) AS taxamount 
      UNION select CONVERT(money,1.43) AS callcharge, CONVERT(money,.01) AS taxamount 
      UNION select CONVERT(money,1.43) AS callcharge, CONVERT(money,.99) AS taxamount 
      UNION select CONVERT(money,1.43) AS callcharge, CONVERT(money,.03) AS taxamount 
     ) dt 

select @DecimalAmount,@MoneyAmount 

我只能得到,如果你有3个或更多的callcharge或TAXAMOUNT小数位的值不同。所以如果你没有这样的数据你就没问题。