3

我正在尝试在 SQL Server 2012 上编写一个查询,该查询将返回包含指定字节序列的 varbinary(max) 列。我可以通过将 varbinary 字段转换为 varchar 并使用 LIKE 的查询来做到这一点:

SELECT * FROM foo
WHERE CONVERT(varchar(max), myvarbincolumn) LIKE 
  '%' + CONVERT(varchar(max), 0x626C6168) + '%'

其中“0x626C6168”是我的目标字节序列。不幸的是,这仅适用于该字段不包含任何值为零 (0x00) 的字节并且这些字节在我的数据中非常常见。我可以采用其他方法来处理包含零值字节的值吗?

4

3 回答 3

2

如果您使用二进制排序规则,它应该可以工作。

WITH foo(myvarbincolumn) AS
(
SELECT 0x00626C616800
)
SELECT *
FROM   foo
WHERE  CONVERT(VARCHAR(max), myvarbincolumn) COLLATE Latin1_General_100_BIN2 
                    LIKE '%' + CONVERT(VARCHAR(max), 0x626C6168) + '%' 

Latin1_General_BIN如果在旧版本的 SQL Server 上,您可能需要(比如说) 。

于 2013-10-31T14:38:03.240 回答
2

不幸的是,Martin 提出的解决方案存在缺陷。

如果搜索关键字中的二进制序列包含任何0x25字节,则将其转换为%字符(根据ASCII表)。

然后,此字符在子句中被解释为通配符like,导致出现许多不需要的结果。

-- 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) + '%');

要解决此问题,请使用以下搜索子句:

-- 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;
于 2018-04-18T17:19:56.950 回答
0

我刚刚发现了这个非常简单的查询

SELECT * FROM foo
WHERE CONVERT(varchar(max), myvarbincolumn,2) LIKE '%626C6168%'
于 2020-07-27T14:46:43.177 回答