2011-01-10 203 views
41

是否有与IsDate或IsNumeric等价的uniqueidentifier(SQL Server)? 还是有什么相当于(C#)TryParse?如何检查一个字符串是否是唯一标识符?

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

我试图掩盖的场景如下:

SELECT something FROM table WHERE IsUniqueidentifier(column) = 1 
+1

我不明白你在做什么试图实现。您想要选择某个列的值是唯一标识符的所有行吗?什么是业务场景?如果一个专栏是为了拥有一个唯一标识符,那么它的值是不是无效或实际上就是唯一标识符?它还能是什么? – 2011-01-10 17:07:57

+0

我使用名称的GUID创建数据库(构建服务器上的集成测试)。我想列出这些数据库(select * from sys.databases IsUniqueidentifier(name)) – Benoittr 2011-01-10 18:12:02

+0

啊,明白了 - 你不是指uniqueidentifier数据类型,只是一个字符串。 – 2011-01-10 19:07:33

回答

38

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

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

对于SQL Server的早期版本中,现有的答案错过意味着他们可能根本无法匹配的字符串,SQL Server将几个点实际上投给UNIQUEIDENTIFIER而没有投诉,或者可能最终导致无效的投射错误。

SQL Server接受包装在{}中的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把铸造尝试的情况下表达,可能会发生铸造是很重要在行被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 + '}%' 
4

我不知道任何东西,你可以使用“开箱即用” - 你必须写上自己, 恐怕。

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

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 

然后,您可以改善它来检查it's只是HEX值。

+8

你的函数认为`------------------------------------`是一个唯一标识符) – onedaywhen 2011-01-11 11:24:50

+0

你可以用onedaywhen的回答结合这样的:'创建FUNCTION [DBO] [IsAGuid(@Data VARCHAR(50))返回SCHEMABINDING位AS \t \t BEGIN \t \t \t回报情况 \t \t \t \t当@Data像' [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] - [O-图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] [O-图9a-FA-F] [0-9A-FA-F] [0-9A-FA-F] [0-9A -FA-F] [0-9A-FA-F]” \t \t \t \t然后1 \t \t \t \t否则为0结束 \t \t END` – andes 2012-10-17 19:36:12

21
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]'; 

UPDATE:

...但我还是通过@喜欢在回答方法r0d30b0y:

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

你可以把它变成一个功能,如pcofre提示:`创建功能[dbo]。[IsAGuid](@Data VARCHAR(50))返回与SCHEMABINDING位AS \t \t BEGIN \t \t \t返回壳体 \t \t \t \t当@Data像“[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] [O-图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]“ \t \t \t \t然后1 \t \t \t \t否则为0结束 \t \t END` – andes 2012-10-17 19:38:23

51

不是我的,发现这个网上...想我会分享。

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

r0d30b0y答案的一个变体是使用PATINDEX为字符串内找到...

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

只好用找一个URL字符串中的GUID ..

HTH

戴夫

0

我用:

ISNULL(convert(nvarchar(50), userID), 'NULL') = 'NULL' 
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! 

*/ 
2

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

WHERE列LIKE“% - % - % - % - %”

0

我曾与AutoFixture,它使用的GUID生成的一些测试用户默认为生成的字段。我需要删除的用户的名字字段是GUID或唯一标识符。我就是这样结束的。

我能够凑齐一些你的答案到这个。

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

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

RLIKE使用MySQL的

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