Подтвердить что ты не робот

Как проверить, является ли строка уникальным идентификатором?

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

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

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

SELECT something FROM table WHERE IsUniqueidentifier(column) = 1
4b9b3361

Ответ 1

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 + '}%' 

Ответ 2

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

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

Ответ 3

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

Ответ 4

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

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

Ответ 5

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

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

Придется найти гиды внутри строки URL.

НТН

Dave

Ответ 6

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

Столбец WHERE, например '% -% -% -% -%'

Ответ 7

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

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

Ответ 8

Вы можете написать свой собственный 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.

Ответ 9

Я использую:

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

Ответ 10

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

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!

*/

Ответ 11

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

Я смог собрать некоторые из ваших ответов.

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