一意の識別子を使用して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文字を超えるすべての文字を無視するようです。これはバグ/機能なのか、設定可能なものなのか?
フロントエンドで長さの検証があるため、大きな問題ではありませんが、私には正しい振る舞いではないようです。
暗黙的な変換は、値が中括弧{...}
で囲まれている場合にも機能します。
これらをクエリに追加した場合、最後の}
が誤った場所に配置されるため、元の値が長すぎると、暗黙的な変換は失敗します。
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.
SQL Serverは、選択を行うときに36文字を超えるすべての文字を無視するようです。これはバグ/機能なのか、設定可能なものなのか?
動作は uniqueidentifier
タイプのBooks Onlineエントリ に記載されています。
参照される例は次のとおりです。
そうは言っても、私は暗黙の変換を避けることを好みます。 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が文字列表現を型付きuniqueidentifier
に定数折りたたみするときに、実行プランで内部的に使用する構文と同じです。
SELECT t.uuid
FROM @T AS t
WHERE
t.uuid = '7DA26ECB-D599-4469-91D4-F9136EC0B4E8';
型指定されたuniqueidentifiers
をSQL Serverとの間でやり取りできるかどうかは、使用しているライブラリによって異なりますが、36文字の文字列は、使用可能なオプションの中で最も望ましくないものだと思います。変換を実行する必要がある場合は、変換を明示的に行い、文字列ではなく16バイトのバイナリ値を使用します。
追加の文字は、暗黙的な変換中に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.
_