#sql #sql-server #binary #bit
#sql #sql-сервер #двоичный #бит
Вопрос:
У меня есть 2 таблицы: одна из них содержит двоичный столбец (128), где каждый бит является некоторым флагом. Также у меня есть другая таблица, содержащая список битовых позиций, которые необходимо проверить в запросе.
Это пример того, как я выполняю запрос для одного бита. Как сделать это универсально, т.Е. Выбрать записи, тестирующие биты в позициях из второй таблицы? Должно ли это быть функцией? что?
DECLARE @nByteNum integer
DECLARE @nBitNumInByte integer
DECLARE @nMask integer
DECLARE @nBigBitNum integer
declare @t table(id int not null identity, id1 int, banner binary(128))
declare @bitpositions table(id int not null identity, position int)
insert into @bitpositions(position) values(8)
insert into @bitpositions(position) values(24)
insert into @bitpositions(position) values(30)
insert into @t(id1, banner)
select 1, 0x0
union all
select 1, 0x000100FF
union all
select 1, 0x010200FF
union all
select 10, 0x010208
union all
select 10, 0x000100
union all
select 10, 0x040000
select * from @t
-- This is for one bit
SET @nBigBitNum= 24
SET @nByteNum= @nBigBitNum/8
SET @nBitNumInByte= @nBigBitNum % 8 -- 0,1...6,7
SET @nMask = POWER(2, @nBitNumInByte ) -- 128,64,... 2,1
SET @nByteNum= @nByteNum 1
select * from @t where SUBSTRING(banner, @nByteNum,1)amp;@nMask=@nMask
Ответ №1:
Побитовые операции в SQL Server не работают с ДВОИЧНЫМИ данными так, как вы ожидаете. Они работают только с целочисленными типами данных, как указано на странице MSDN для amp; (побитовое И).
Общий синтаксис для проверки значений с битовой маской в запросе: WHERE {Column} amp; {BitMaskedValue} = {BitMaskedValue}
.
Посмотрите на следующие примеры, используя желаемый сценарий попытки найти записи, в которых включены разрядные позиции 8 и 16.
-- 24 = 16 8
SELECT 24 amp; 16 -- 16
SELECT 24 amp; 8 -- 8
SELECT 24 amp; 17 -- 16
SELECT 24 amp; 32 -- 0
SELECT 24 amp; 26 -- 24
Комментарии:
1. Да, но этот запрос работает правильно: выберите * из @t, где SUBSTRING(banner, @nByteNum,1)amp;@nMask=@nMask; . Еще один вопрос, как оптимизировать запросы к большим таблицам? какие-нибудь хитрости? 🙂