如何检查字符串是否是唯一标识符?

问题描述 投票:48回答:12

uniqueidentifier(SQL Server)是否等效于IsDate或IsNumeric?或者有什么等同于(C#)TryParse?

否则我将不得不编写自己的功能,但我想确保我不会重新发明轮子。

我想要涵盖的场景如下:

SELECT something FROM table WHERE IsUniqueidentifier(column) = 1
sql sql-server
12个回答
59
投票

使用TRY_CONVERT(UNIQUEIDENTIFIER, expression),SQL Server 2012使这一切变得更加容易

SELECT something
FROM   your_table
WHERE  TRY_CONVERT(UNIQUEIDENTIFIER, your_column) IS NOT NULL;

对于SQL Server的早期版本,现有的答案会遗漏几个点,这意味着它们可能不匹配SQL Server实际上会在没有投诉的情况下投射到UNIQUEIDENTIFIER的字符串,或者可能最终导致无效的投射错误。

SQL Server接受包含在{}中的GUID或没有这个的GUID。

另外,它会忽略字符串末尾的无关字符。例如,SELECT CAST('{5D944516-98E6-44C5-849F-9C277833C01B}ssssssssss' as uniqueidentifier)SELECT CAST('5D944516-98E6-44C5-849F-9C277833C01BXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' as uniqueidentifier)都成功了。

在大多数默认排序规则下,LIKE '[a-zA-Z0-9]'最终将匹配ÀË等字符

最后,如果将结果中的行转换为uniqueidentifier,则将转换尝试放在case表达式中非常重要,因为在WHERE过滤行之前可能会发生转换。

所以(借用@r0d30b0y's idea)可能会有一个更强大的版本

;WITH T(C)
     AS (SELECT '5D944516-98E6-44C5-849F-9C277833C01B'
         UNION ALL
         SELECT '{5D944516-98E6-44C5-849F-9C277833C01B}'
         UNION ALL
         SELECT '5D944516-98E6-44C5-849F-9C277833C01BXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
         UNION ALL
         SELECT '{5D944516-98E6-44C5-849F-9C277833C01B}ssssssssss'
         UNION ALL
         SELECT 'ÀD944516-98E6-44C5-849F-9C277833C01B'
         UNION ALL
         SELECT 'fish')
SELECT CASE
         WHEN C LIKE expression + '%'
               OR C LIKE '{' + expression + '}%' THEN CAST(C AS UNIQUEIDENTIFIER)
       END
FROM   T
       CROSS APPLY (SELECT REPLACE('00000000-0000-0000-0000-000000000000', '0', '[0-9a-fA-F]') COLLATE Latin1_General_BIN) C2(expression)
WHERE  C LIKE expression + '%'
        OR C LIKE '{' + expression + '}%' 

0
投票

我用 :

ISNULL(convert(nvarchar(50), userID), 'NULL') = 'NULL'

0
投票

我有一些使用AutoFixture生成的测试用户,默认情况下使用GUID生成字段。我需要删除的用户的My FirstName字段是GUID或uniqueidentifier。这就是我在这里结束的方式。

我能够把你的一些答案凑到一起。

SELECT UserId FROM [Membership].[UserInfo] Where TRY_CONVERT(uniqueidentifier, FirstName) is not null


0
投票

使用RLIKE进行MYSQL

SELECT 1 WHERE @StringToCompare
RLIKE REPLACE('00000000-0000-0000-0000-000000000000', '0', '[0-9a-fA-F]');

56
投票

不是我的,在网上找到了......我以为我会分享。

SELECT 1 WHERE @StringToCompare LIKE 
       REPLACE('00000000-0000-0000-0000-000000000000', '0', '[0-9a-fA-F]');

23
投票
SELECT something 
  FROM table1 
 WHERE column1 LIKE '[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]';

更新:

...但我更喜欢@ r0d30b0y的答案中的方法:

SELECT something 
  FROM table1 
 WHERE column1 LIKE REPLACE('00000000-0000-0000-0000-000000000000', '0', '[0-9a-fA-F]');

4
投票

我不知道任何你可以“开箱即用”的东西 - 你必须自己写这个,我害怕。

如果你可以:尝试在C#库中编写它并将其作为SQL-CLR程序集部署到SQL Server中 - 那么你可以使用像Guid.TryParse()这样的东西,它肯定比T-SQL中的任何东西都更容易使用....


2
投票

r0d30b0y答案的变体是使用PATINDEX在字符串中查找...

PATINDEX('%'+REPLACE('00000000-0000-0000-0000-000000000000', '0', '[0-9a-fA-F]')+'%',@StringToCompare) > 0

不得不用来在URL字符串中查找Guids ..

HTH

戴夫


1
投票

这是一个基于一些早期评论的概念的函数。这个功能非常快。

CREATE FUNCTION [dbo].[IsGuid] (@input varchar(50))  
    RETURNS bit AS  
BEGIN

RETURN 
    case when @input like '[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]'
    then 1 else 0 end
END
GO

/* 
Usage: 

select [dbo].[IsGuid]('123') -- Returns 0
select [dbo].[IsGuid]('ebd8aebd-7ea3-439d-a7bc-e009dee0eae0') -- Returns 1

select * from SomeTable where dbo.IsGuid(TableField) = 0 -- Returns table with all non convertable items!

*/

1
投票

喜欢保持简单。 GUID有四个 - 在它中甚至,如果只是一个字符串

WHERE列如'% - % - % - % - %'


1
投票

虽然是一篇较老的帖子,但只是考虑进行快速测试......

SELECT  [A].[INPUT],
        CAST([A].[INPUT] AS [UNIQUEIDENTIFIER])
FROM   (
            SELECT '5D944516-98E6-44C5-849F-9C277833C01B' Collate Latin1_General_100_BIN AS [INPUT]
            UNION ALL
            SELECT '{5D944516-98E6-44C5-849F-9C277833C01B}'
            UNION ALL
            SELECT '5D944516-98E6-44C5-849F-9C277833C01BXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
            UNION ALL
            SELECT '{5D944516-98E6-44C5-849F-9C277833C01B}ssssssssss'
            UNION ALL
            SELECT 'ÀD944516-98E6-44C5-849F-9C277833C01B'
            UNION ALL
            SELECT 'fish'
        ) [A]
WHERE   PATINDEX('[^0-9A-F-{}]%', [A].[INPUT]) = 0

0
投票

您可以编写自己的UDF。这是一个简单的近似,以避免使用SQL-CLR程序集。

CREATE FUNCTION dbo.isuniqueidentifier (@ui varchar(50))  
RETURNS bit AS  
BEGIN

RETURN case when
    substring(@ui,9,1)='-' and
    substring(@ui,14,1)='-' and
    substring(@ui,19,1)='-' and
    substring(@ui,24,1)='-' and
    len(@ui) = 36 then 1 else 0 end

END
GO

然后,您可以对其进行改进,以检查它是否与HEX值有关。

© www.soinside.com 2019 - 2024. All rights reserved.