2009-09-25 3 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. callcharge и taxamount - оба типа данных денег.

Это первый случай, когда я столкнулся с этим условием, но я перемещаю некоторый связанный код с производством и был «попрошен» исследовать это.

Что вы думаете? Существует ли странность между деньгами и десятичными типами данных? Что-нибудь еще, что вы думаете, может объяснить это?

+0

где @nBalance объявлен? – Shawn

+0

отредактирован, чтобы добавить объявление :) –

+0

Единственное, что я не уверен в количестве данных. вы можете попробовать преобразовать денежные поля в десятичные 8,2 и посмотреть, изменились ли результаты – Shawn

ответ

0

Какие типы данных являются callcharge и taxamount? Я бы сделал все мои вычисления в этом типе данных и сбрасывал их в десятичные числа в конце. В настоящее время все ваши промежуточные вары являются десятичными, что означает, что ошибки округления сложны. Не раунд до конца.

+0

Callcharge and taxamount - это деньги типы данных. –

1

Я не вижу каких-либо типов данных денег в вашем коде, но я предполагаю, что call.callcharge &10 call.taxamount есть? Я не знаю о точности проблемы.

Возможно, самое лучшее, что вы можете сделать, это попытаться найти конкретный тестовый пример, где данные имеют это несоответствие, и посмотреть, можете ли вы последовательно воспроизводить его. Затем вы можете разобрать логику заявления за раз и выяснить, где введено несоответствие.

Возможно ли, что у вас есть нулевая плата или нулевое налогообложение? (null + (- $ 0.02)) => null; может быть

isnull(sum(callcharge+taxamount),0) 

должно быть:

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

@unbilledCallsAmount или @ArBalance также может быть пустым, если эти заявления выберите не возвращают никаких записей. НТН,

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 , Поэтому, если у вас нет таких данных, вы в порядке.

0

Ваши деньги (из комментариев) столбцы преобразуются в десятичные числа (8,2) из-за datatype precedence. И money-> numeric (near end) округлены они округлены

Таким образом, оба @unbilledCallsAmount и @ArBalance будут округлены, и все это будет накапливаться.

Смежные вопросы