0

このアプリケーションでは、ユーザーが他のデータベース列を数値として使用して算術式 (+ - * /) を入力できるようにします。数値はアプリケーションによって解析され、計算列としてデータベースに書き込まれます。

select *ただし、ゼロ除算、算術オーバーフロー、およびまだ遭遇していない可能性のある他のものなど、テーブルを使用するときに例外を引き起こす可能性のある式をユーザーが作成できるようにすることで発生する問題があります(ただし、それがすべてだと思います)。彼ら)。

データベースに例外をスローさselect *せることは、絶対に壊滅的です。エラーが発生しやすいデータがある場合に正常に失敗するように、式を書き直すことをお勧めします。

ゼロ除算の場合、ソリューションは非常に簡単です。

add [Col] as case {divisor} when 0 then N'DIVIDE-BY-ZERO' else {expression} end

私の質問は、算術オーバーフローに対して何ができるでしょうか? 列に二段または明らかに間違ったデータを表示することは問題ではありませんが、例外をスローすることは問題になります。

4

4 に答える 4

1

解析テクノロジがあるため、式を書き直して、ゼロ除算、オーバーフロー、さまざまな型へのアップキャストなど、多数の CASE ステートメントで発生する可能性のあるすべての問題をトラップできます。

しかし、このツールがコード生成ツールであり、ユーザーがエッジの式を確認してテストする責任を負わない限り、これらをスキーマの一部としてデータベースに入れることは素晴らしい考えだとは思わないので、私はそうしません。元のデータベース設計に含まれていたかのように条件を変更します。

既に式を解析している場合は、これもクライアント側でコンパイルし、行ごとにエラーを処理します。

TRY/CATCHを使用して例外をキャッチすることは、行ごとではなく、オール オア ナッシングのシナリオです。

于 2009-12-21T19:05:06.717 に答える
1

目標に実際には近づけない答えを受け入れるのを見るのは嫌いです.

少し役立つかもしれない別の答えとして、計算列に(決定論的)スカラーUDFを呼び出すようにすることができます。

たとえば、ここを参照してください

したがって、計算列を作成する場合は、生成された UDF (または複数の UDF) に列を渡し、そこで作業を行うようにします。スカラー UDF では、問題をキャッチするためのコードをたくさん持つことができますが、それでも を使用することはできませんTRY/CATCH。スカラー UDF でできることは、ケースをキャッチして適切な回答を返すことです (おそらく NULL をバブルアップします)。

ただし、スカラー UDF ではパフォーマンスが非常に悪くなります (非永続インライン計算列と UDF については不明です。主に永続化を使用します)。挿入と更新を少し遅くします。それは大きなトレードオフです。

于 2009-12-22T18:05:28.887 に答える
0

例外をキャッチするのはどうですか?一般的な例外は言うまでもなく、算術オーバーフローの考えられるすべての原因を検出しようとするのは難しいようです。

例外として、元のユーザー定義の結果セットと互換性のあるナンセンスな結果セットを返すことができます。

begin try
    select exp(999)
end try
begin catch
    select 1
end catch 
于 2009-12-21T18:50:56.383 に答える
0

パフォーマンスが重要な場合は、トリガーまたはインデックス付きビューを使用して、データが挿入、更新、または削除されたときに計算を保存します。

パフォーマンスが重要でない場合は、スカラー値関数を使用してください。

于 2009-12-22T21:13:36.700 に答える