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 …
)之后的字母,但这种最后的方法让我提出这个问题:
如何仅查询(非 - )十六进制字段?
答案 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