Запрос двоичного столбца с использованием, как в SQL Server

Я использую SQL Server 2008. В моей таблице есть столбец с именем TestData типа binary,

Пример данных в столбце TestData:

1. 0x0001DC780C0030373156635D0C00B8840301009A0600AC
2. 0x0301DC780C0030373156385D0C006499C401009A0600AC

Ниже написано два запроса, чтобы получить строки, где TestData начинается с "0x0001". Но никто из них не работает.

SELECT * 
FROM T_TRANSACTION 
WHERE  CAST(Indicium AS nvarchar(MAX)) LIKE '0x0001%'

----No results found

SELECT * 
FROM T_TRANSACTION 
WHERE  CAST(Indicium AS nvarchar(MAX)) LIKE '0x0001%'

----Returns all the rows

Пожалуйста, исправьте запрос, чтобы получить ожидаемые результаты

2 ответа

Решение

Не конвертируйте его, но рассматривайте как диапазон (как если бы вы использовали значения даты и времени)

DECLARE @foo TABLE (TestData varbinary(100) NOT NULL);
INSERT @foo (TestData) VALUES
         (0x0001DC780C0030373156635D0C00B8840301009A0600AC),
         (0x0001AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA),
         (0x0001AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF),
         (0x0301DC780C0030373156385D0C006499C401009A0600AC),
         (0x0301FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF),
         (0x0302000000000000000000000000000000000000000000);

SELECT *
FROM @foo
WHERE TestData >= 0x0001 AND TestData < 0x0002;

-- added more digit for clarity of what actually happens
SELECT *
FROM @foo
WHERE TestData >= 0x00010000 AND TestData < 0x00020000;

SELECT *
FROM @foo
WHERE TestData >= 0x0001AA AND TestData < 0x0001AB;

SELECT *
FROM @foo
WHERE TestData >= 0x0301 AND TestData < 0x0302;

Это дает возможность использовать индекс на TestData

Редактировать, вы просто указываете столько цифр, сколько вам нужно

Для сравнения с ведущим префиксом LIKE подойдет ответ gbn. Для реальной эквивалентности поиска строк LIKE вы можете использовать LIKE следующим образом:
(заимствование схемы и примеров данных из @gbn)

DECLARE @foo TABLE (TestData varbinary(100) NOT NULL);
INSERT @foo (TestData) VALUES
         (0x0001DC780C0030373156635D0C00B8),
         (0x0001AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA),
         (0x0001AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF),
         (0x0301DC780C0030373156385D0C006499C401009A0600AC),
         (0x0301FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF),
         (0x0302000000000000000000000000000000000000000000);

SELECT *
FROM @foo
WHERE CAST(TestData AS VARCHAR(MAX)) LIKE '%'+CAST(0xDC78 AS VARCHAR(MAX))+'%';

Когда вы приводите двоичное значение к VARCHAR, все, что он делает, это обрабатывает необработанные биты как строковый поток. Он волшебным образом не преобразует его в строковое представление. Рассмотрим пример ниже:

select cast(0x41 as varchar(10));     -- Result: A
select cast(0x414263 as varchar(10)); -- Result: ABc

Потому что байт 0x41 или порядковый номер 65 - это "A" в стандартной латинской кодовой странице.

Не используйте массив байтов как строку, используйте его как число.

все, что вам нужно сделать, это:

ВЫБЕРИТЕ * ИЗ T_TRANSACTION, ГДЕ Индикация>= 0x0001

или если вы хотите получить конкретный:

ВЫБЕРИТЕ * FROM T_TRANSACTION WHERE Indicium >=0x0001DC780C0030373156635D0C00B8840301009A0600AC

Другие вопросы по тегам