Запрос двоичного столбца с использованием, как в 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