2016-06-21 36 views
2

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


如果我有GUID的其中有些是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

相关问题