选择中仍然匹配额外字符的唯一标识符

Chr*_*ium 18 sql-server t-sql sql-server-2012

我们正在使用带有唯一标识符的 SQL Server 2012,我们注意到在执行选择时在末尾添加了额外的字符(所以不是 36 个字符),它仍然返回与 UUID 的匹配项。

例如:

select * from some_table where uuid = '7DA26ECB-D599-4469-91D4-F9136EC0B4E8' 
Run Code Online (Sandbox Code Playgroud)

返回带有 uuid 的行7DA26ECB-D599-4469-91D4-F9136EC0B4E8

但是如果你运行:

select * from some_table where uuid = '7DA26ECB-D599-4469-91D4-F9136EC0B4E8EXTRACHARS'
Run Code Online (Sandbox Code Playgroud)

它还返回带有 uuid 的行7DA26ECB-D599-4469-91D4-F9136EC0B4E8

SQL Server 在进行选择时似乎忽略了 36 以外的所有字符。这是错误/功能还是可以配置的东西?

这不是一个大问题,因为我们在前端验证了长度,但对我来说这似乎不是正确的行为。

Pau*_*ite 11

SQL Server 在进行选择时似乎忽略了 36 以外的所有字符。这是错误/功能还是可以配置的东西?

该行为记录在Books Online 条目中的uniqueidentifier类型

BOL 条目摘录

参考的例子是:

提单示例

话虽如此,我更愿意避免隐式转换。一个uniqueidentifier文本可以直接在T-SQL中使用ODBC转义语法键入:

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}'};
Run Code Online (Sandbox Code Playgroud)

这与 SQL Server 在将字符串表示形式常量折叠为 typed 时在执行计划中内部使用的语法相同uniqueidentifier

SELECT t.uuid 
FROM @T AS t 
WHERE 
    t.uuid = '7DA26ECB-D599-4469-91D4-F9136EC0B4E8';
Run Code Online (Sandbox Code Playgroud)

在 uuid 上查找索引

您是否可以将类型传入uniqueidentifiers和传出SQL Server 可能取决于您使用的库,但 36 个字符的字符串在我看来是可用选项中最不理想的。如果您必须执行转换,请使它们显式,并使用 16 字节的二进制值而不是字符串。


Aar*_*and 10

在隐式转换期间,SQL Server 会简单地忽略(嗯,静默地截断)附加字符。例如:

SELECT CONVERT(UNIQUEIDENTIFIER, '7DA26ECB-D599-4469-91D4-F9136EC0B4E8EXTRACHARS');
Run Code Online (Sandbox Code Playgroud)

结果:

------------------------------------
7DA26ECB-D599-4469-91D4-F9136EC0B4E8
Run Code Online (Sandbox Code Playgroud)

这与这个场景没有什么不同:

DECLARE @x VARCHAR(1) = 'xyz';
SELECT @x;
Run Code Online (Sandbox Code Playgroud)

结果:

----
x  
Run Code Online (Sandbox Code Playgroud)

你不能配置这个,但如果你想让你的变量转换失败,那么你可以尝试CHAR(36)先把变量塞进一个表中,这将因截断而失败:

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

结果:

Msg 8152, Level 16, State 14, Line 2
String or binary data would be truncated.
The statement has been terminated.
Run Code Online (Sandbox Code Playgroud)


Mik*_*son 10

如果值包含在大括号中,则隐式转换也有效{...}

如果您在查询中添加这些,如果原始值太长,则隐式转换将失败,因为最后一个}在错误的位置结束。

select * 
from some_table 
where uuid = '{'+'7DA26ECB-D599-4469-91D4-F9136EC0B4E8'+'}'
Run Code Online (Sandbox Code Playgroud)

如果您尝试转换

SELECT CONVERT(UNIQUEIDENTIFIER, '{'+'7DA26ECB-D599-4469-91D4-F9136EC0B4E8EXTRACHARS'+'}');
Run Code Online (Sandbox Code Playgroud)

你得到

Msg 8169, Level 16, State 2, Line 1
Conversion failed when converting from a character string to uniqueidentifier.
Run Code Online (Sandbox Code Playgroud)