Articles

SQL Serverの末尾のスペース

今週のビデオをYouTubeで見る

ずっと前に、ユーザー入力をキャプチャするアプリケーションを構築しました。 このアプリケーションの特徴は、ユーザーの入力と値のデータベースを比較することでした。

このアプリはSQL Serverストアドプロシージャの一部としてこのテキスト比較を実行し、必要に応じて将来ビジネスロジックを簡単に更新できます。

ある日、あるユーザーから、入力した値が一致してはいけないことがわかっているデータベース値と一致しているというメールを受け取りました。

, それは私がsql Serverのカウンタ直感的な等価比較を発見した日です末尾のスペース文字を扱うとき。

空白を埋め込む

CHARデータ型は、定義された長さに達するまでスペースで値を埋め込むことをおそらく認識しています。

LEN()関数は文字列の文字数を示し、DATALENGTH()関数はその文字列で使用されるバイト数を示します。

この場合、DATALENGTHは10に等しくなります。, この結果は、定義されたCHARの長さ10を埋めるために、文字”a”の後に埋め込まれたスペースが発生するためです。 これは、値を十六進に変換することで確認できます。 値61(hexの”a”)に続いて”20″の値(スペース)が表示されます。

変数のデータ型をVARCHARに変更すると、値にスペースが埋め込まれなくなります。

これらのデータ型のいずれかがスペース文字で値を埋め込み、もう一方がスペース文字で値を埋め込むことを考えると、両者を比較するとどうなりますか?,

この場合、DATALENGTHsが異なることを確認できますが、SQL Serverでは両方の値が等しいと見なされます。

ただし、この動作は混合データ型の比較で発生するだけではありません。 同じデータ型の二つの値を、いくつかの空白文字を含む一つの値と比較すると、何かが発生します。..予期しない:

二つの変数の値が異なるにもかかわらず、SQL Serverではこれらの値が等しいと見なされます。,

末尾に空白を含む文字を追加すると、同じ動作が表示されます。

両方の値は明らかに異なりますが、SQL Serverではそれらが互いに等しいと見なされます。 等号をLIKE演算子に切り替えると、物事が少し変わります。

ワイルドカード文字のないLIKEは等号のように動作すると思いますが、SQL Serverはこれらの比較を同じように実行しません。,

等号比較に戻り、文字値の前にスペースを付けると、異なる結果が表示されます。

SQL Serverでは、文字列の末尾にスペースがあるかどうかにかかわらず、二つの値が等しいと見なされます。 ただし、文字列の前にあるスペースは一致しなくなりました。

何が起こっているのですか?

ANSI

直感的ではありますが、SQL Serverの機能は正当化されます。, SQL Serverは、文字列を比較するためのANSI仕様に従っており、文字列に空白を追加して、比較する前に同じ長さになるようにします。 これは私たちが見ている現象を説明します。

ただし、LIKE演算子ではこれを行いませんが、これは動作の違いを説明します。

余分なスペースが重要なときの比較

末尾のスペースの違いが重要な比較をしたいとしましょう。

一つのオプションは、私たちが戻っていくつかの例を見たようにLIKE演算子を使用することです。, ただし、これはLIKE演算子の典型的な使用ではありませんので、クエリがそれを使用して何をしようとしているのかをコメントして説明してください。 あなたが望む最後のことは、ワイルドカード文字が表示されないため、コードの将来のメンテナが等号に切り替えることです。 私が見たもう一つのオプションは、値の比較に加えてDATALENGTH比較を実行することです。

このソリューションは、すべてのシナリオに適しているわけではありません。, まず、SQL Serverが値比較またはDATALENGTH述語を最初に実行するかどうかを知る方法はありません。 この難破した男のインデックスの使用を起こしている。

異なるデータ型のフィールドを比較する場合、より深刻な問題が発生する可能性があります。, たとえば、VARCHARとNVARCHARデータ型を比較する場合、DATALENGTHを使用した比較クエリが誤検知を引き起こすシナリオを作成するのは非常に簡単です。

ここで、NVARCHARはすべての文字に2バイトを格納し、単一の文字NVARCHARのDATALENGTHsは文字+スペースVARCHAR値に等しくなります。

これらのシナリオで行うべき最善のことは、データを理解し、特定の状況に合わせて機能する解決策を選択することです。,

挿入する前にデータをトリミングするかもしれません(そうするのが理にかなっている場合)!