2011-08-25 16 views
5

ColumnAにCAST関数(FLOATに対して)を実行するSQLがあります。 SQLには、最終的にColumnAに数値以外の値を持つ行を間接的にフィルタするフィルタがあります。しかし、私がパラレルでSQLの部分を実行することによると信じているので、CASTはフィルタされた行にも適用され、SQLは "floatとして値をキャストできません" 「float型の値をキャストできません

私はSQLが期待通りに動作することを

OPTION (MAXDOP 1) 

をクエリヒントを追加することにより、1つのPROCで実行した場合ことを知っています。私は1 procで実行すると、その値のキャスティングが成功するようにcolumnAの非数値の行を除外するためにフィルタを強制的に適用すると思われます。私はまた、クエリヒントを使用して

OPTION (FORCE ORDER) 

修正問題、私はあまりにもbecausethisを想定していますが、フィルタが最初に適用され、私は1つが、1気筒で実行されているより良いクエリのパフォーマンスを得るされることを確実にすることがわかりました。

私は第2のオプションを使用して問題を修正しています。もし私がここで何が起こっているのかについての誤解がある場合、あるいは私の一般に解説したいと思う人が解説したいと思う人がいるなら、それを感謝します。

私は、Microsoft SQL Server 2008 R2(RTM)

上で実行しています - 10.50.1720.0(X64)2010年6月12日1時34分59秒 著作権(c)マイクロソフトコーポレーションのEnterprise Edition (64 Windows NT 5.2上のビット)(3790ビルドします:サービスパック2)

付け足し:いいだろうと思われ

は、T-SQLの文字列ができたかどうかを確認するには、以下の機能を持っていたあります〜する特定のデータ型に変換されます。

IsFloat IsNumeric関数 IsInteger など

私は実際にどのように多くの列VARCHAR(255)のように定義されている私は、私達のデータベースで検索するデータのすべての種類のに悩まされています。私は解決策は「そうしない」と思う。

+2

SQLを表示できますか? – MatBailie

+1

実際に車を見ずに車の修理をお手伝いしています。私たちに車を見せてください。 – JNK

+0

T-SQLにはIsNumericの – MatBailie

答えて

4

あなたの考えについて。

文字列を特定のデータ型に変換できるかどうかを調べるには、T-SQLに以下の機能があります。

この場合、SQL Server 2012ではTRY_CONVERTが導入されています。したがって、次のクエリはエラーではなくNULLを返します。

SELECT TRY_CONVERT (FLOAT, 'Fish') 

でもSELECTが評価される前WHERE句がどうなるシリアル計画に保証はありません。 SQL Server 2005以降のin this blog postで説明したように、これは以前のバージョンよりも発生する可能性が高くなります。 Behavior Changes to Database Engine Features in SQL Server 2005は、具体的には以下のように呼び出します。これらはSQL Serverで評価されたときに

SQL Server 2005は、時には早く よりもクエリで式を評価し、2000年この動作は 次の重要な利点を提供します。

  • に計算列のインデックスを一致させる能力計算式の列式と同じクエリ内の式。
  • 表現結果の冗長計算の防止。この動作に関する

もっと議論はクレイグ・フリードマンConversion and Arithmetic Errorsによって別の良いブログの記事です。

2012年以前のバージョンでは、TRY_CONVERTの場合、CAST AS FLOATCASEにラップする必要があります。例えばまだ

SELECT CASE WHEN ISNUMERIC(Col)=1 THEN CAST(Col AS FLOAT) END AS Col 
    FROM Table 
    WHERE ISNUMERIC(Col)=1 

これは絶対にだけ値が文書化されてAn example of an input that would fail is '.'

CASEをfloatにはむしろ、具体的よりも数値データ型のいずれかにキャストすることを確認し、あなたが自分自身ISNUMERICとしてエラーを取得しないことを保証されていない、ほとんどオンラインブックの短絡(some exceptions are discussed here

また、接続項目SQL Server should not raise illogical errorsとSQLKiwi

によって good explanation of a similar issueにこの程度の追加議論/苦情を見つけることができます
1

私はあなたが正しいと信じています。 CONVERT()関数は、述部が行を間接的にフィルター処理する前に適用されています。

例外を回避するには正しいですが、1つの方法は、実行計画の操作の順序を制御することです。ステートメントのヒントがあなたのために働いているなら、あなたはそれと一緒に行くことができます。 (個人的にヒントは私の最後の手段です)

SQL ServerにはIsNumeric関数があります。

IsNumeric関数は、IsNumericテストを "渡しますが数値データ型に変換されたときに例外を発生させる"値があるという意味では、やや不適切です。

個人的に、私はこのアプローチで行くことに傾向がある:

select convert(float,case when isnumeric(t.foo)=1 then t.foo else null end) 

ではなく、文レベルのヒントを。

また、変換しない値を「フィルタリング」する他の述語を指定します。

select convert(float,case when t.fi in ('fo','fum') then t.foo else null end) 
関連する問題