さまざまなフォーラムを 1 時間近く探し回った結果、SQL サーバーは単純な算術計算に関しては少し馬鹿げているという結論に達しました。
最近まで問題なく機能していた機能を利用しようとしています。使用中のフォームの別の情報セットの値の一部を変更すると、先に奇妙な動作が発生します。
問題は、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ステートメントを実行することで呼び出されますが、結果は管理スタジオ内から関数を呼び出すのと同じです:
SELECT dbo.Liability('ClientID','RecordID','PHP') AS Liability
単項マイナスがどのように SQL の数学処理を壊す傾向があるかについて読んでいますが、それを打ち消す方法が完全にはわかりません。
この関数の最後の愚かなトリック: 関数のままにしておく必要があります。ストアドプロシージャを利用できないフロントエンドで使用する必要があるため、ストアドプロシージャに変換できません。
SQLサーバーは括弧を気にしますか? それとも無視しているだけですか?