在各种论坛上搜索了将近一个小时后,我得出的结论是,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 甚至关心括号吗?还是只是无视他们?