如何检查VARCHAR字符串是否(非)十六进制?

时间:2016-06-21 08:33:21

标签: sql-server tsql hex string-conversion base36

TL; DR 如何在选择行时测试字符串是否为十六进制?

如果我有一个带有GUID的表,其中一些是Base36而不是十六进制:

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

我希望获得所有具有非专有十六进制GUID的行。

对于单身人士,我可以尝试CONVERT(VARBINARY(32),[GUID],2)并查看它是否失败,但在查询中我不能这样做。如果我可以查询WHERE isNaN(parseInt(GUID,16)),那么它将是故障安全的(同时必须应用于所有行)。

当然我可以全文搜索F(WHERE [GUID] LIKE '%g%' OR [GUID] LIKE '%h%' OR …)之后的字母,但这种最后的方法让我提出这个问题:

如何仅查询(非 - )十六进制字段?

5 个答案:

答案 0 :(得分:2)

只需将 LIKE 与通配符用于特定范围:

SELECT * FROM [GUIDs] WHERE [GUID] LIKE '%[g-z]%';

答案 1 :(得分: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]%'

答案 2 :(得分: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行。

答案 3 :(得分: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, '0123456789ABCDEFGHIJKLMNOPQRSTUV' union all
select 3, 'DEADBEAF4D15EA5EDEFEC8EDFEE1DEAD' union all
select 4, 'cafeBABECAFED00DB16B00B515badA55'
) q;

答案 4 :(得分:0)

在postgres中,您可以使用POSIX regular expressions

select "GUID" ~ '[0-9A-F]{32}' as is_hex from the_table;

上面的代码检查字符串的长度是否也为32