2010-11-19 10 views
1

私はSQL Serverでこのアドホッククエリ(UserIdがNVARCHARフィールドであると仮定)しようとすると:この場合、SQL Serverの暗黙の型キャストはどのように機能しますか?

SELECT * FROM MyUser WHERE UserId = 123456 

を、私はこのエラーを取得する:

 
Msg 245, Level 16, State 1, Line 1 
Syntax error converting the nvarchar value 'foo' to a column of data type int. 

は明らか値'foo'はどこかダウンしていますUserIdの列。

なぜSQL Serverが私の目に見えるようなことをするのではなく、列全体をINTEGERに変換しようとしていますか?検索値をNVARCHARに変換しますか?

+0

なぜそれがそれをしているのかわかりません。しかし、それは常にそうです:) –

答えて

3

比較はData Type Precedenceのルールを使用して行われる:

When an operator combines two expressions of different data types, the rules for data type precedence specify that the data type with the lower precedence is converted to the data type with the higher precedence.

NVARCHARタイプ(優先25)int(優先16)に変換されます。優先順位1は「最高」を意味することに注意してください。

+0

+1それはまさに私が自分の言葉で何とか説明しようとしたことです。この素晴らしいリンクをありがとう! =) –

+0

これは、クエリオプティマイザがクエリをエンジンに渡す前に処理できるはずのものだと思います。検索値を動作するタイプに変換し、警告を発行して取り除きます。まぁ。 :-) – Tomalak

+0

@Tomalak:SQL Serverの今後のリリースになるかもしれません! = P Hehehe ... –

2

これは、異なるタイプの2つの値を比較できないためだと思います。次に、等価コンパートメントメンバを同じ型に変換する必要があります。ここでは、intが好きです。

nvarcharタイプよりも優先度がintだから、暗黙的にnvarcharをint値に変換しようとする必要があります。

EDIT#1

"But wouldn't it be sensible to try and convert the value I have given to the type of the field I am searching in, instead of the other way around?"

それがなかった場合は、[はい、これはいいだろう。しかし、私は、他の種類の比較をしようとすると、変換が多すぎることを暗示しようとしているからです。最初の例で

where dateOfBirth = N'1976-06-16' 

where dateOfBirth = 1976-6-16 

は、ユーザの意図は何ですか? dateOfBirthが日付値1976-06-16と等しいかどうか、または1976 - 6 - 16の整数値と比較すると、結果は1954となり、任意の日付の年と見なすことができます。

nvarchardatetimeのような暗黙的な変換があると思いますが、多くはカバーする必要があるため、最も一般的な変換に限定されていました。

+0

私は、私が探しているフィールドの型に与えた値を、他の方法の代わりに、試して変換することは賢明ではないでしょうか? – Tomalak

+1

うん。 UserIDにプライマリキーがあり、テーブルにあるものを探す場合でも、結果を見つけることができますが、あなたもエラーが発生しました。つまり、一致していない別の行からエラーとして返された結果行が返されます.Oracleもこれを実行します。私はそれがデフォルトの型昇進/変換ルールの副作用だと思います。 –

+0

'dateOfBirth = 1976-6-16'の意図は明らかに' 1976 - 6 - 16'の算術結果です。 DATETIMEは数値型ですが、ユーザーは数値入力(式にもかかわらず)を与えました。もし文字列( 'N'1976-06-16'')を与えると、サーバ*はそれを使用する前にDATETIMEに変換されます。そうしないと、これらのクエリは機能しません。私の質問に書かれている状況で同じことをするには、実際には十分にスマートであるかもしれません。 ;-)しかし、私は物事が彼らの方法であることを感謝します。 – Tomalak

1

なぜ列がNVARCHARであることがわかっている場合は、整数値を指定していますか?

多くのSQL実装のように、SQL Serverはタイプサポートで他の言語の後ろで長い道のりです。型チェックは通常、実行時にのみ実行されます。したがって、あなたのようなクエリは、あなたがここにあるような問題を強調するために構文チェックされていません。異なる種類の不一致があるため、クエリに誤りがありますが、SQL Serverがそれを無効にしないため、結果はデー​​タに応じて予測できなくなります。

+0

なぜですか?それは臨時の質問だったので、今度は引用符を入力することは考えていませんでした。私はちょうどエラーメッセージの巨大な愚かさに驚いて、それの背後に深い根拠があるのか​​疑問に思った。確かに、そうではありません - それは "まさにその通り"です。 – Tomalak

+0

@Tomalak:より良いエラーメッセージは「型の不一致」ですが、解決方法は変わりません。正しいタイプの値を指定するためにクエリを修正してください。 – sqlvogel

+0

私はメッセージ*の文言が愚かであるとは言いませんでしたが、私はSQL Server *が状況を処理する方法を愚かだと言っています。 ;-) – Tomalak

関連する問題