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