3

私の問題は非常に単純なようですが、私はここで立ち往生しています。「SrcID」という「nvarchar」列を持つテーブルがあり、その中に数値と文字列の両方を格納しています。さて、「結合」状態でその列の「IsNumeric」をチェックしようとすると、次のようになります。

   ISNUMERIC(SrcID) = 1 AND SrcID > 15

次のエラーが発生します。

  Msg 245, Level 16, State 1, Line 47
  Conversion failed when converting the nvarchar value 'Test' to data type int.

驚くべきことに、「SrcID> 15」のチェックを外すと、クエリは正しく実行されます。このステートメントに他に何かを含める必要がありますか?

問題の修正を手伝ってください。前もって感謝します!!

4

2 に答える 2

4

データベースがフィルタリング式を評価する順序を当てにすることはできません。SQLを評価し、最高のパフォーマンスが得られると認識したものに基づいてクエリを実行する計画を作成するクエリオプティマイザがあります。

このコンテキストでIsNumeric()は、インデックスと一緒に使用することはできません。これは、テーブル内のすべての行に対して関数を実行することを意味します。したがって、最高のパフォーマンスを提供することはほとんどありません。これを、インデックスと一致する可能性のある式(存在する場合)と比較してくださいSrcID > 15。インデックスが存在しない場合でも、単一の演算子式にすぎません。IsNumeric()また、関数を実行する必要がある潜在的な行の数をフィルタリングするために使用することもできます。

これは、ビュー、サブクエリ、CTE、CASEステートメント、または計算列を使用して回避できる可能性があります。CTEの例を次に示します。

With NumericOnly As 
(
    SELECT <columns> FROM MyTable WHERE IsNumeric(SrcID) = 1
)
SELECT <columns> FROM NumericOnly WHERE SrcID > 15

そして、ここにCASEステートメントオプションがあります:

SELECT <columns> FROM MyTable WHERE CASE WHEN IsNumeric(SrcIC) = 1 THEN Cast(SrcID As Int) ELSE 0 END > 15
于 2012-01-17T15:01:44.937 に答える
3

句内のフィルターは、WHERE特定の順序で評価されません。

これはSQLServerの一般的な誤解です。オプティマイザーは、最も高速/最も簡単であると思われる条件をチェックし、可能な限り最も効率的な方法でデータを制限しようとします。

あなたの例では、おそらくにインデックスがSrcIDあり、オプティマイザは、最初に結果をの場所に制限してから、それらすべての行で関数を実行する方が速いと考えていSrcID > 15ます(関数はそれ以外の場合はすべての行をチェックする必要があるため)。

次のような括弧を使用して、操作の順序を強制することができます。

WHERE (ISNUMERIC(SrcID) = 1) AND SrcID > 15

または、caseステートメントを使用します。

WHERE CASE WHEN ISNUMERIC(SrcID) = 1 THEN SrcID > 15 ELSE 1=0 END

于 2012-01-17T15:01:27.763 に答える