Reputation: 1107
I am trying to write a query on SQL Server 2012 that will return varbinary(max) columns that contain a specified byte sequence. I am able to do that with a query that converts the varbinary field to varchar and uses LIKE:
SELECT * FROM foo
WHERE CONVERT(varchar(max), myvarbincolumn) LIKE
'%' + CONVERT(varchar(max), 0x626C6168) + '%'
where "0x626C6168" is my target byte sequence. Unfortunately, this works only if the field does not contain any bytes with the value zero (0x00) and those are very common in my data. Is there a different approach I can take that will work with values that contain zero-valued bytes?
Upvotes: 3
Views: 9513
Reputation: 5184
I just discovered this very simply query.
SELECT * FROM foo
WHERE CONVERT(varchar(max), myvarbincolumn,2) LIKE '%626C6168%'
The characters 0x aren't added to the left of the converted result for style 2.
Upvotes: 1
Reputation: 3512
Unfortunately the solution proposed by Martin has a flaw.
In case the binary sequence in the search key contains any 0x25
byte, it will be translated to the %
character (according to the ASCII table).
This character is then interpreted as a wildcard in the like
clause, causing many unwanted results to show up.
-- A table with a binary column:
DECLARE @foo TABLE(BinCol VARBINARY(MAX));
INSERT INTO @foo (BinCol) VALUES (0x001125), (0x000011), (0x001100), (0x110000);
-- The search key:
DECLARE @key VARBINARY(MAX) = 0x1125; -- 0x25 is '%' in the ASCII table!
-- This returns ALL values from the table, because of the wildcard in the search key:
SELECT * FROM @foo WHERE
CONVERT(VARCHAR(max), BinCol) COLLATE Latin1_General_100_BIN2
LIKE ('%' + CONVERT(VARCHAR(max), @key) + '%');
To fix this issue, use the search clause below:
-- This returns just the correct value -> 0x001125
SELECT * FROM @foo WHERE
CHARINDEX
(
CONVERT(VARCHAR(max), @key),
CONVERT(VARCHAR(max), BinCol) COLLATE Latin1_General_100_BIN2
) > 0;
Upvotes: 2
Reputation: 453298
If you use a binary collation it should work.
WITH foo(myvarbincolumn) AS
(
SELECT 0x00626C616800
)
SELECT *
FROM foo
WHERE CONVERT(VARCHAR(max), myvarbincolumn) COLLATE Latin1_General_100_BIN2
LIKE '%' + CONVERT(VARCHAR(max), 0x626C6168) + '%'
You might need (say) Latin1_General_BIN
if on an older version of SQL Server.
Upvotes: 2