Как проверить, является ли строка уникальным идентификатором? - PullRequest
49 голосов
/ 10 января 2011

Есть ли эквивалент для IsDate или IsNumeric для uniqueidentifier (SQL Server)? Или есть что-нибудь эквивалентное (C #) TryParse?

В противном случае мне придется написать свою собственную функцию, но я хочу убедиться, что я не изобретаю колесо заново.

Сценарий, который я пытаюсь охватить, следующий:

SELECT something FROM table WHERE IsUniqueidentifier(column) = 1

Ответы [ 12 ]

61 голосов
/ 02 октября 2012

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]' в конечном итоге совпадает с такими символами, как À или Ë

Наконец, если приведение строк в результате к уникальному идентификатору важно поместить попытку приведения в выражение case, так как приведение может произойти до того, как строки будут отфильтрованы с помощью WHERE.

Итак (заимствуя @ r0d30b0y идею ), немного более надежная версия может быть

;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 + '}%' 
57 голосов
/ 06 марта 2012

Не мой, нашел это онлайн ... думал, что поделюсь.

SELECT 1 WHERE @StringToCompare LIKE 
       REPLACE('00000000-0000-0000-0000-000000000000', '0', '[0-9a-fA-F]');
23 голосов
/ 11 января 2011
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 голосов
/ 10 января 2011

Я не знаю ничего, что вы могли бы использовать "из коробки" - боюсь, вам придется написать это самостоятельно.

Если вы можете: попробуйте написать это внутри библиотеки C # и развернуть ее на SQL Server как сборку SQL-CLR - тогда вы можете использовать такие вещи, как Guid.TryParse(), что, безусловно, гораздо проще в использовании, чем что-либо в T-SQL ....

2 голосов
/ 31 января 2017

Хотелось бы, чтобы все было просто.У GUID есть четыре - даже четные, если это просто строка

WHERE столбец типа '% -% -% -% -%'

2 голосов
/ 22 февраля 2016

Вариант ответа r0d30b0y - использовать PATINDEX для поиска в строке ...

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

Пришлось использовать, чтобы найти Guids в строке URL.

НТН

Dave

1 голос
/ 25 августа 2017

Хотя старый пост, просто мысль для быстрого теста ...

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
1 голос
/ 15 октября 2016

Эта функция основана на концепции некоторых предыдущих комментариев. Эта функция очень быстрая.

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!

*/
0 голосов
/ 28 февраля 2018

Используйте RLIKE для MYSQL

SELECT 1 WHERE @StringToCompare
RLIKE REPLACE('00000000-0000-0000-0000-000000000000', '0', '[0-9a-fA-F]');
0 голосов
/ 18 апреля 2017

У меня было несколько тестовых пользователей, которые были созданы с помощью AutoFixture, которая по умолчанию использует GUID для сгенерированных полей.Мои поля FirstName для пользователей, которых мне нужно удалить, - это GUID или уникальные идентификаторы.Вот так я и оказался здесь.

Мне удалось собрать воедино некоторые из ваших ответов.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...