SQL 服务器 GUID 有时有效有时无效

SQL Server GUID sometimes valid and sometimes not

我遇到了一个 GUID 问题,我已将其缩小为 LIKE 运算符的问题。

当以下是运行在我的服务器

DECLARE @Problem NVARCHAR(1000) = N'58C21BC6-081B-4E57-BFE1-5B11AAC662F1';

DECLARE @GuidPattern NVARCHAR(1000) = 
    REPLICATE('[0-9A-Fa-f]', 8)
    + '-'
    + REPLICATE('[0-9A-Fa-f]', 4)
    + '-'
    + REPLICATE('[0-9A-Fa-f]', 4)
    + '-'
    + REPLICATE('[0-9A-Fa-f]', 4)
    + '-'
    + REPLICATE('[0-9A-Fa-f]', 12);

SELECT
    CASE
        WHEN @Problem LIKE @GuidPattern THEN 1
        ELSE 0
    END AS [FollowsPattern];

答案是 0,但是当我 运行 在本地机器上使用完全相同的代码时,答案是 1

在我看来很明显该字符串实际上是一个有效的 GUID,因此在这两种情况下答案都应该是 1。我知道的所有其他确认 GUID 有效的方法也都成功了,无论是在本地还是在服务器上:

SELECT
    CASE
        WHEN CAST(@Problem AS UNIQUEIDENTIFIER) = @Problem THEN 1
        ELSE 0
    END AS [IsGuid1]; -- 1

SELECT
    CASE
        WHEN CONVERT(UNIQUEIDENTIFIER, @Problem) = @Problem THEN 1
        ELSE 0
    END AS [IsGuid2]; -- 1

SELECT
    CASE
        WHEN TRY_CONVERT(UNIQUEIDENTIFIER, @Problem) IS NOT NULL THEN 1
        ELSE 0
    END AS [IsGuid3]; -- 1

服务器版本为

Microsoft SQL Server 2016 (RTM) - 13.0.1601.5 (X64) 
    Apr 29 2016 23:23:58 
    Copyright (c) Microsoft Corporation
    Enterprise Edition: Core-based Licensing (64-bit) on Windows Server 2012 R2 Standard 6.3 <X64> (Build 9600: ) (Hypervisor)

而我的本地安装版本是

Microsoft SQL Server 2014 - 12.0.2000.8 (X64)
    Feb 20 2014 20:04:26
    Copyright (c) Microsoft Corporation
    Express Edition (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1) 

默认排序规则不同(SQL_Latin1_General_CP1_CI_AS 本地和 Danish_Norwegian_CI_AS 在服务器上),但我认为这无关紧要,因为我正在处理 Unicode。 在任何一台机器上添加额外的 COLLATE 子句与另一台机器的排序规则没有区别。 更新: 不正确,排序规则是来源的问题。我只在变量声明中测试了不同的排序规则,而不是在比较本身。

我想问题出在排序规则上。

看看:http://rextester.com/IRQEFU33639

如果您使用默认排序规则:

SELECT
    CASE
        WHEN @Problem LIKE @GuidPattern THEN 1
        ELSE 0
    END AS [FollowsPattern];

结果 = 1

相反,如果您强制 Danish_Norwegian_CI_AS 排序规则:

SELECT
    CASE
        WHEN @Problem collate Danish_Norwegian_CI_AS  LIKE @GuidPattern THEN 1
        ELSE 0
    END AS [FollowsPattern];

它returns0.

我建议将排序规则强制为 SQL_Latin1_General_CP1_CI_AS 或其他运行良好的排序规则。

SELECT
    CASE
        WHEN @Problem COLLATE SQL_Latin1_General_CP1_CI_AS LIKE @GuidPattern THEN 1
        ELSE 0
    END AS [FollowsPattern];

为了方便起见,可以使用 INLINE User Defined Function

强制使用标准排序规则

SELECT
    CASE
        WHEN @Problem COLLATE Latin1_General_CI_AS LIKE @GuidPattern COLLATE Latin1_General_CI_AS THEN 1
        ELSE 0
    END AS [FollowsPattern];

原因是 "a" 在 Danish_Norwegian_CI_AS 排序规则中的匹配方式。

有关我用 Danish_Norwegian_CI_AS

演示的更多信息,请参阅 SQL 'Like' operator and 'aa'