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'
我遇到了一个 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'