Обновите один определенный бит в поле битовой маски (SQL Server) - PullRequest
0 голосов
/ 27 сентября 2019

У меня есть столбец int, содержащий 8 битов в моей базе данных SQL Server.Как я могу обновить определенный бит, не затрагивая другие?

Например, у меня есть значение

11010000 

, и я хочу установить бит 1 и бит 2 на 1, чтобы он стал

11010011

Просматривал побитовые операторы, но не мог найти правильное решение.

Моя цель не только обновить определенный бит, но и избежать блокировок базы данных.

Так что, когда транзакция1обновляет бит 1 в определенной записи, другая транзакция 2 может обновлять бит 2 в том же поле той же записи в то же время.

Возможно ли это?Или единственное использование 8 отдельных bit столбцов?

Ответы [ 2 ]

0 голосов
/ 27 сентября 2019

Значение псевдо-набора битов - это когда у вас есть целое число или строка, которая при выборе или печати выглядит как набор битов.Примерно так:

DECLARE @bits varchar(8) = '1010'

SELECT Right(8, REPLICATIE('0', 8) + @bits

Value returned: 00001010

Для этого типа набора битов вы должны помнить, что вы не устанавливаете биты, а вместо этого представляете биты, и вам необходимо установить представление битов втак же.Например, приведенная ниже функция может использоваться для установки битов в строковом представлении вашей цепочки битов:

CREATE FUNCTION dbo.SetBitInString 
    (
    @Source char(8), 
    @Position int,
    @Action char(1) = 'S',
    @Value bit = NULL
    )
RETURNS Char(8)
AS
BEGIN
    DECLARE @work Char(8) = '00000000'
    SET @work = Right(@work + ISNULL(LTRIM(RTRIM(@Source)), ''), 8)
    SET @Work = 
        CASE @Action
            WHEN 'S'-- Set
                THEN Stuff(@Work, @Position, 1, '1')
            WHEN 'R' -- Reset
                THEN Stuff(@Work, @Position, 1, '0')
            WHEN 'X' -- XOR value with position
                THEN STUFF(@Work, @Position, 1, CAST(CAST(SubString(@Work, @Position, 1) as int) ^ ISNULL(@Value, 0) as CHAR(1)))
            WHEN 'Q'
                THEN '1'
            ---- add other options as needed - this is a quick example.
            ELSE @Action
        END
    IF (@Action = @Work)
        RAISERROR('Bad Action (%s) Submitted', 13, 1, @Action)

    RETURN @Work
END

Чтение бит - это простая ПОДПИСЬ.Константы могут быть определены для значения каждого бита (например, DECLARE @ShowTotalPrice = 4 -- The 4th bit is the Show Total Price flag)

. Этого должно быть достаточно для продолжения, если вы хотите использовать этот стиль настройки, где отображаемое значение - это ваш битрейт, представленный в 1 с.и 0s.

0 голосов
/ 27 сентября 2019

То, что вы ищете, это побитовые операции.Чтобы всегда включать правильный бит, используйте побитовое ИЛИ.Итак, чтобы включить биты 1 и 2 (общее значение = 3), используйте такой оператор (предполагается, что значение в @value равно 208 или 11010000 в двоичном виде):

SET @value = @value | 3
-- or, the alternate form
SET @value |= 3

Другие операторы являются побитовымиИ (SET @value = @value & 3), и побитовое НЕ (SET @Value = @value ~ 3), и побитовый XOR (SET @value = @value ^ 3).

Тем не менее, наличие восьми полей bit логически проще для нового программиста.Мне не нужно искать что-то особенное, чтобы увидеть, что поле ShowCurrencySymbol является флагом для отображения символа валюты, а не для выяснения того, что делает пятый бит в байте.И, поскольку поля сжимаются внутри, так что восемь однобитных ненулевых полей = один байт используемого пространства (добавление NULL занимает два бита на бит).

Наконец, вы не можете иметь две транзакцииодновременно обновить поле в той же строке.Пока происходит одно обновление, строка будет заблокирована, что не позволит обработать другое обновление.Если вы действительно хотите что-то подобное, вам придется использовать гораздо более широкий метод - отдельную таблицу BitValues ​​или Flags, что-то вроде этого:

CREATE TABLE Flags (
    RowID int not null,
    FlagName varchar(16) Not Null,
    BitValue bit not null,
    CONSTRAINT PK_Flags PRIMARY KEY (RowID, FlagName)
    );

Затем вы читаете и пишете свои флаги из этой таблицы отдельноиз ряда.

...