web-dev-qa-db-ja.com

なぜ0が空の文字列に等しいのですか?

次のT-SQLステートメントが1(true)を返す理由を見つけるには、助けが必要です。

SELECT IIF( 0 = '', 1, 0)

誰かがSET ANSI_NULLSのようなANSIオプションまたは動作を引き起こしている何かを変更したと思います。

私の問題は、いくつかの値を結合していて、最後の行セットに0''の値で結合された値があることですが、これは正しくありません。

23
gotqn

これは文書化された動作です。誰もが設定をいじったとは思わない。

MSDNの data type precedence を参照してください。

演算子が異なるデータ型の2つの式を組み合わせる場合、データ型の優先順位の規則は、優先順位の低いデータ型を優先順位の高いデータ型に変換することを指定します。

コメントに記載されているように、空の文字列は数値型では0に変換され、日付に変換すると1900-01-01 00:00:00.000に変換されます。

編集:あなたの本当の問題は、あなたのデザインが異なるデータ型のフィールドで結合しなければならないようになっていることだと思います。これを回避する唯一の方法は、クエリのパフォーマンスを低下させる結合句を変換することです。主な問題はおそらくスキーマの設計にあります

編集:チャットに移動されたコメントで多くの議論がありました。どのように見えても不合理ですが、空の文字列を他のデータ型に変換すると、任意の値が生成されます。

このコード:

SELECT CONVERT(int, '')
SELECT CONVERT(float, '')
SELECT CONVERT(date, '')
SELECT CONVERT(datetime, '')

この出力を生成します:

0
0
1900-01-01
1900-01-01 00:00:00.000

この動作は他の先行するデータ型間で一貫していると期待でき、0を日付に変換すると同じ任意の値が生成されると期待できますが、そうではありません。

SELECT CONVERT(date, 0)

生産する

データ型intから日付への明示的な変換は許可されていません。

サポートされている変換ではないため

ながら

SELECT CONVERT(datetime, 0)

戻り値

1900年1月1日00:00:00

そう、それは奇妙で恣意的ですが、実際に文書化され、説明可能です。