1

非常に大きなストアドプロシージャの最後に実行される次のステートメントがあります。

UPDATE myTable
SET    DiffPerc = CAST(CASE
                         WHEN ( CASE
                                  WHEN SimExt = 0
                                       AND StdExt = 0 THEN 0
                                  WHEN StdExt = 0 THEN 99999
                                  ELSE SimExt - StdExt / StdExt
                                END ) * 100 > 99999 THEN 99999
                         ELSE ( CASE
                                  WHEN SimExt = 0
                                       AND StdExt = 0 THEN 0
                                  WHEN StdExt = 0 THEN 99999
                                  ELSE SimExt - StdExt / StdExt
                                END ) * 100
                       END AS DECIMAL(8, 2)) 

アイデアは、ある値と別の値のパーセンテージの差を決定するフィールドがあるということです。フィールドDiffPercは〜のパーセント差SimExtですStdExt。このルーチンは1年以上もの間毎日機能していますが、2日前から、次のエラーメッセージが表示されるようになりました。

数値をデータ型数値に変換する際の算術オーバーフローエラー。

DECIMAL (8, 2)このメッセージの意味は理解できますが、埋め込まれたcaseステートメントの要点は、分母の0をテストすることと、値がフィールドにパックされる前に非常に高い値のパーセンテージをチェックすることの両方です。

私は何が欠けていますか?このステートメントを更新して、考えられるすべてのエッジケースを考慮し、オーバーフローが発生する前に処理するにはどうすればよいですか?

99999また、パーセントとしてハードコードされた値は、誰かが何かを台無しにしたことをエンドユーザーに示すフラグであることに注意してください。

4

4 に答える 4

1

タイプミスかもしれませんが、一連のパレテシスが欠落しているように思われます。

つまり

(SimExt - StdExt) / StdExtSimExt - 1それ以外の場合は、除算後に減算が行われるため、常に実行します。

違いに注意してください:

select CAST((99999999 - 99999998) / 99999998 as decimal(8,2))
select CAST(99999999 - 99999998 / 99999998 as decimal(8,2))
于 2012-08-20T09:30:15.667 に答える
0

最終結果はサイズ(8,2)を超えます。スケールを大きくする必要があります

于 2012-08-17T13:58:04.953 に答える
0

おそらく範囲外の高い値です。に変更してみてください

  (CASE  
   WHEN SimExt = 0 AND StdExt = 0 THEN 0  
   WHEN StdExt = 0 THEN 99999  
   when simext>1000000 then null
   ELSE SimExt - StdExt / StdExt  
   END) * 100 > 99999 
于 2012-08-17T14:00:15.077 に答える
0

SQLは短絡評価を行わないため、そのためにSQLを保護する必要があります。 http://en.wikipedia.org/wiki/Short-circuit_evaluation

実際には、両方のケースを評価し、最後に正しいパスを選択します。

于 2012-08-17T14:11:06.977 に答える