これは、float
にキャストできない行がテーブルに少なくとも1つあることを意味します 。 CASE
を実行する 安全ですが、CTEを組み合わせてWHERE句を追加すると、T-SQLを作成するときにプログラマーの一般的な誤謬に陥ります。宣言の順序は実行の順序を意味します 。プログラマーは、言語のようなCの命令型手続き型スタイルに慣れており、SQLの宣言型セットベースの性質を理解できません。私は以前にこの問題について書き、誤謬がエラーを引き起こす場合の例を示しました:
完全なコードを投稿すると、あなたのケースでどこで誤謬を犯し、特定の実行順序を想定したかがわかります。
更新後
OK、それで私はあなたの場合、コードが実行の順序、result
で正しいことを管理する必要があります CASE
を最初に評価せずに列を投影することはできません 。 CASEがWHERE句に含まれていたら、状況は異なっていたでしょう。
問題は異なります: ISNUMERIC
。この関数は、NUMERIC
が何であるかを非常に寛大に理解しています。 意味し、以前に多くの開発者を噛んだことがあります。つまり、CASTとCONVERTが拒否する値を受け入れます。カンマを含むもののように:
declare @n varchar(8000) = '1,000';
select isnumeric(@n);
select cast(@n as float);
select case when isnumeric(@n)=1 then cast(@n as float) else null end;
したがって、ISNUMERIC
を渡す値があります テストしますが、変換に失敗します。頭を上げるだけで、このアプローチを深く掘り下げるほど、より多くの閉じたドアが見つかります。サーバー側で必要なキャストを行うための安全な方法はありません。理想的には、データモデルを修正します(フロートを格納する場合はフィールドをフロートにします)。それが足りない場合は、データをトリアージし、適切なフロートではないすべての値を削除し、フロントエンド/アプリケーションを修正して新しい値を導入しないようにします。次に、新しい不正な値が表示された場合にエラーをトリガーする制約を追加します。クエリでこれを解決することはできません。その道路には体が散らばっています。
SQL Serverの次のバージョンでは、新しい関数 TRY_CONVERT
、それで問題は解決します。