为什么SQL Server会给我错误的输出?

sni*_*kid 1 sql sql-server ssms

我在SSMS中发现了一个类似bug的行为.我使用以下查询从名为Candidate的表中查询.

 select CandidateId, CandidateName from Candidate
 where CandidateId='73415005-77C6-4D4B-9947-02D6B148E03F2'
Run Code Online (Sandbox Code Playgroud)

我是复制粘贴CandidateId这是一个唯一的标识符,但不知怎的,我最后添加了两个(2).实际上,我查询的候选人ID是' 73415005-77C6-4D4B-9947-02D6B148E03F'而且没有候选人候选人73415005-77C6-4D4B-9947-02D6B148E03F2(我甚至认为这不是GUID)

但是,我仍然得到了结果.

在此输入图像描述

您可以在查询和结果中看到,CandidateId是不同的.为什么会这样?有人请解释一下.

Mla*_*dic 5

由于您的列CandidateId属于GUID类型,因此条件的右(字符串)部分将转换为uniqueidentifier数据类型并被截断.您可以在执行计划中看到这一点.索引搜索/扫描运算符中将有一个标量运算符(CONVERT_IMPLICIT(uniqueidentifier,[@ 1],0)).


Tom*_*ica 5

那是因为你的执行计划中可能有一个convert_implicit,并且SQL将'73415005-77C6-4D4B-9947-02D6B148E03F2'转换为guid.

在此输入图像描述


Gor*_*off 5

顶级描述是字符串被转换为唯一标识符,因此忽略最后一个数字.

这个逻辑记录在案.首先,唯一标识符的运算符优先级略高于字符串.在相关的部分文件:

  1. 唯一标识符
  2. nvarchar(包括nvarchar(max))
  3. NCHAR
  4. varchar(包括varchar(max))
  5. 烧焦

这就是转换uniqueidentifier而不是字符串的原因.

其次,这是SQL Server执行"静默转换"的情况.也就是说,它会转换前36个字符,并且不会为较长的字符串生成错误.这也记录在案:

以下示例演示了当转换为的数据类型的值太长时截断数据.由于uniqueidentifier类型限制为36个字符,因此超出该长度的字符将被截断.

所以,你看到的行为不是一个错误.它是记录在案的行为,结合了记录的SQL Server功能的两个不同方面.