2016-06-21 10 views
2

TL; DR Как проверить, является ли строка шестнадцатеричной при выборе строк?Как проверить, являются ли строки VARCHAR шестнадцатеричными?


Если бы я был стол с GUIDs, где некоторые из них являются base36 вместо если шестнадцатеричное:

ID | GUID 
    ===|================================= 
    1 | CAFEBABECAFED00DB16B00B515BADA55 
    2 |ABCDEFGHIJKLMNOPQRSTUV 
    3 | DEADBEAF4D15EA5EDEFEC8EDFEE1DEAD 

Я хочу, чтобы все строки с идентификаторами GUID, которые не являются исключительно шестнадцатеричное.

Для одноточечного я могу попробовать CONVERT(VARBINARY(32),[GUID],2) и посмотреть, не сработает ли он, но я не могу этого сделать в запросе. Если бы я мог запросить WHERE isNaN(parseInt(GUID,16)), он был бы отказоустойчивым (при этом он должен применяться ко всем строкам).

Конечно, я мог бы найти полный текст письма следующих F (WHERE [GUID] LIKE '%g%' OR [GUID] LIKE '%h%' OR …), но этот последний курорт такого подхода привел меня к задаю этот вопрос:

Как запросить для (не) шестнадцатеричном только поля?

ответ

2

Просто используйте LIKE с шаблонным символом для определенного диапазона:

SELECT * FROM [GUIDs] WHERE [GUID] LIKE '%[g-z]%'; 
2
;WITH rw AS 
(
    SELECT '0000AF0012B' ishexornot 
    UNION ALL 
    SELECT '0000AF0012G' 
    UNION ALL 
    SELECT '0000AF0012 ' 
) 
SELECT *, CASE WHEN ishexornot LIKE '%[^0-9A-F]%' THEN 0 ELSE 1 END 
FROM rw 

так

WHERE [GUID] LIKE '%[^0-9A-F]%'

+0

Пользуется CTE, значимый для реальной идеи? – dakab

+0

@ dakab CTE здесь, чтобы заполнить некоторые данные. –

0

Если вы заботитесь о чувствительности к регистру, то отсортированному вероятно, необходимо.
Поскольку поведение по умолчанию LIKE в основном нечувствительно к регистру.

select Id, [Guid], 
(CASE WHEN [Guid] collate sql_latin1_general_cp1_cs_as NOT LIKE '%[^0-9A-F]%' THEN 1 ELSE 0 END) as isHex 
from (
select 1 as Id, 'CAFEBABECAFED00DB16B00B515BADA55' as [Guid] union all 
select 2, 'ABCDEFGHIJKLMNOPQRSTUV' union all 
select 3, 'DEADBEAF4D15EA5EDEFEC8EDFEE1DEAD' union all 
select 4, 'cafeBABECAFED00DB16B00B515badA55' 
) q; 
1

Начиная с SQL Server 2012, вы можете использовать TRY_CONVERT():

declare @t table (
    Id int identity (1,1) primary key, 
    Value varchar(100) not null 
); 

insert into @t (Value) 
values 
('F6AA1EE0-DF55-43E8-92ED-B2A84E621485'), 
('F32E4621CE004C47889DEBDA9BA790AF'), 
('09F94C95-9004-4C7C-8F5D-9CA374546288'), 
('5DAFD4C7-C780-4F32-9BF1-52027371546A'), 
('4D81BD419BFE42EA956E715023EF3B77'); 

select t.* 
from @t t 
where try_convert(uniqueidentifier, t.Value, 2) is null; 

В отличие от CONVERT(), запрос в образце работает без ошибок, и возвращает строки 2 и 5.

+0

Это SQL Server 2008 R2. Однако давайте предположим, что вопрос имеет значение-агностик. Как вы используете 'try_convert' и как это помогает? – dakab

+0

Спасибо, теперь он гораздо более всеобъемлющий. Эта встроенная функция была явно задумана именно для этой цели. Я только надеюсь, что смогу использовать его когда-нибудь. – dakab