0

在各种论坛上搜索了将近一个小时后,我得出的结论是,SQL Server 对简单的算术有点愚蠢。

我正在尝试使用一个直到最近似乎还可以正常工作的功能。在为正在使用的表单上的一组不同信息更改一些值后,我得到了奇怪的行为。

问题是它给了我基于 excel 电子表格公式的错误结果。

公式如下所示:

=IF(D8=0,0,(((D8*C12-C16)*(100-C13)/100+C16)/D8)+(C18*D8))

我的 SQL 如下所示:

(((@DaysBilled * @ContractRate - @ActualPlanDed) * (100 - @InsCover) / 100 + @ActualPlanDed) / @DaysBilled) + (@CoPay * @DaysBilled)

用给定的数据填充变量如下所示:

(((11 * 433 - 15) * (100 - 344) / 100 + 15) / 11) + (15 * 11)

更奇怪的是,如果我在服务器环境中手动使用上面的数字(在每个值的末尾添加 .00),它会给我 -11405.1200000000

根据我给出的值,它应该是 166.36。不幸的是,我得到 -886.83

这是整个函数及其调用方式:

ALTER FUNCTION Liability
(
@ClientGUID CHAR(32),
@RecordGUID CHAR(32),
@Type CHAR(3)
)
RETURNS DECIMAL(18,2) AS
BEGIN

DECLARE @ReturnValue decimal(18,2);

    DECLARE @DaysBilled int;
    DECLARE @ContractRate decimal(18,2);
    DECLARE @ActualPlanDed decimal(18,2);
    DECLARE @InsCover decimal(18,2);
    DECLARE @CoPay decimal(18,2);

IF (@Type = 'RTC')
BEGIN   
        SELECT @DaysBilled = RTCDaysBilled, 
                @ContractRate = CAST(REPLACE(REPLACE(ContractRateRTC, ' ',''),'$', '') AS DECIMAL(6,2)),
                @ActualPlanDed = RTCActualPlanDed, 
                @InsCover = InsRTCCover, 
                @CoPay = RTCCoPay
        FROM AccountReconciliation1
        WHERE @ClientGUID = tr_42b478f615484162b2391ef0b2c35ddc
        AND @RecordGUID = tr_abb4effa0d9c4fe98c78cb4d2e21ba5d
END
IF (@Type = 'PHP')
BEGIN   
        SELECT @DaysBilled = PHPDaysBilled, 
                @ContractRate = CAST(REPLACE(REPLACE(ContractRatePHP, ' ',''),'$', '') AS DECIMAL(6,2)),
                @ActualPlanDed = PHPActualPlanDed, 
                @InsCover = InsPHPCover, 
                @CoPay = PHPCoPay
        FROM AccountReconciliation1
        WHERE @ClientGUID = tr_42b478f615484162b2391ef0b2c35ddc
        AND @RecordGUID = tr_abb4effa0d9c4fe98c78cb4d2e21ba5d
END
IF (@Type = 'IOP')
BEGIN   
        SELECT @DaysBilled = IOPDaysBilled, 
                @ContractRate = CAST(REPLACE(REPLACE(ContractRateIOP, ' ',''),'$', '') AS DECIMAL(6,2)),
                @ActualPlanDed = IOPActualPlanDed, 
                @InsCover = InsIOPCover, 
                @CoPay = IOPCoPay
        FROM AccountReconciliation1
        WHERE @ClientGUID = tr_42b478f615484162b2391ef0b2c35ddc
        AND @RecordGUID = tr_abb4effa0d9c4fe98c78cb4d2e21ba5d
END
        IF (@DaysBilled <> 0)
    BEGIN
        SET @ReturnValue = (((@DaysBilled * @ContractRate - @ActualPlanDed)
        *
        (100 - @InsCover) / 100 + @ActualPlanDed)
        /
            @DaysBilled
        )
        +
        (@CoPay * @DaysBilled)
    END
        ELSE
    BEGIN
        SET @ReturnValue = 0;
    END
RETURN @ReturnValue;
END

它是通过从我们的前端运行 select 语句来调用的,但结果与从 management studio 中调用该函数相同:

SELECT dbo.Liability('ClientID','RecordID','PHP') AS Liability

我一直在阅读一元减号如何破坏 SQL 的数学处理,但我不完全确定如何抵消它。

这个函数的最后一个愚蠢的技巧:它必须保持一个函数。我无法将其转换为存储过程,因为它必须与我们的前端一起使用,而前端无法使用存储过程。

SQL Server 甚至关心括号吗?还是只是无视他们?

4

1 回答 1

1

计算是正确的,如果您使用浮点值而不是整数,它当然会有所不同。

对于 (((11 * 433 - 15) * (100 - 344) / 100 + 15) / 11) + (15 * 11) 大约 -886.xx 的值取决于使用整数/浮点数的位置是正确的,什么让你相信它应该是 166.36?

于 2012-11-29T23:37:46.993 回答