選択で一致する余分な文字を含む一意の識別子


19

一意の識別子を使用してSQL Server 2012を使用していますが、末尾に追加文字(36文字ではない)を追加して選択すると、UUIDとの一致が返されることに気付きました。

例えば:

select * from some_table where uuid = '7DA26ECB-D599-4469-91D4-F9136EC0B4E8' 

行をuuidで返します7DA26ECB-D599-4469-91D4-F9136EC0B4E8

しかし、あなたが実行した場合:

select * from some_table where uuid = '7DA26ECB-D599-4469-91D4-F9136EC0B4E8EXTRACHARS'

また、uuidを持つ行を返します7DA26ECB-D599-4469-91D4-F9136EC0B4E8

SQL Serverは、選択を行うときに36を超えるすべての文字を無視するようです。これはバグ/機能または構成可能なものですか?

フロントエンドで長さの検証を行っているため、大きな問題ではありませんが、私には正しい動作とは思えません。

回答:


10

暗黙の変換は、値が中括弧で囲まれている場合にも機能します{...}

これらをクエリに追加すると、元の値が長すぎると暗黙の変換が失敗します。これは、最後の値が}間違った場所にあるためです。

select * 
from some_table 
where uuid = '{'+'7DA26ECB-D599-4469-91D4-F9136EC0B4E8'+'}'

変換しようとした場合

SELECT CONVERT(UNIQUEIDENTIFIER, '{'+'7DA26ECB-D599-4469-91D4-F9136EC0B4E8EXTRACHARS'+'}');

あなたが得る

Msg 8169, Level 16, State 2, Line 1
Conversion failed when converting from a character string to uniqueidentifier.

10

SQL Serverは、選択を行うときに36を超えるすべての文字を無視するようです。これはバグ/機能または構成可能なものですか?

動作は、次のuniqueidentifierタイプのBooks Onlineエントリに記載されています。

BOLエントリー抽出

参照される例は次のとおりです。

BOLの例

そうは言っても、暗黙的な変換は避けたいと思います。uniqueidentifierリテラルは、ODBCエスケープ構文を使用してT-SQLで直接入力することができます。

DECLARE @T AS TABLE
(
    uuid uniqueidentifier UNIQUE NOT NULL
);

INSERT @T (uuid)
SELECT {guid '{7DA26ECB-D599-4469-91D4-F9136EC0B4E8}'};

SELECT t.uuid 
FROM @T AS t 
WHERE 
    t.uuid = {guid '{7DA26ECB-D599-4469-91D4-F9136EC0B4E8}'};

これは、SQL Serverが、文字列表現をtypedに定数で畳むときに実行計画で内部的に使用する構文と同じuniqueidentifierです。

SELECT t.uuid 
FROM @T AS t 
WHERE 
    t.uuid = '7DA26ECB-D599-4469-91D4-F9136EC0B4E8';

uuidでのインデックスシーク

uniqueidentifiersSQL Serverとの間で型指定を受け渡すことができるかどうかは、使用しているライブラリによって異なりますが、36文字の文字列は利用可能なオプションの中で最も望ましくないものであると思います。変換を実行する必要がある場合は、変換を明示的に行い、文字列ではなく16バイトのバイナリ値を使用します。


9

追加の文字は、暗黙的な変換中にSQL Serverによって単純に無視されます(静かに切り捨てられます)。例えば:

SELECT CONVERT(UNIQUEIDENTIFIER, '7DA26ECB-D599-4469-91D4-F9136EC0B4E8EXTRACHARS');

結果:

------------------------------------
7DA26ECB-D599-4469-91D4-F9136EC0B4E8

これは、このシナリオとは異なります。

DECLARE @x VARCHAR(1) = 'xyz';
SELECT @x;

結果:

----
x  

これを設定することはできませんが、変数の変換を失敗させたい場合は、変数をCHAR(36)最初にテーブルに詰め込もうとすることができますが、切り捨てが原因で失敗します:

DECLARE @x TABLE(y CHAR(36));
INSERT @x SELECT '7DA26ECB-D599-4469-91D4-F9136EC0B4E8EXTRACHARS';

結果:

Msg 8152, Level 16, State 14, Line 2
String or binary data would be truncated.
The statement has been terminated.
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.