Логическое «НЕ» в T-SQL не работает с типом данных «бит»?

82

При попытке выполнить одну логическую операцию НЕ оказывается, что в MS SQL Server 2005 следующий блок не работает

DECLARE @MyBoolean bit;
SET @MyBoolean = 0;
SET @MyBoolean = NOT @MyBoolean;
SELECT @MyBoolean;

Вместо этого я добиваюсь большего успеха с

DECLARE @MyBoolean bit;
SET @MyBoolean = 0;
SET @MyBoolean = 1 - @MyBoolean;
SELECT @MyBoolean;

Тем не менее, это выглядит немного извращенным способом выражения чего-то столь же простого, как отрицание.

Я что-то упускаю?

Джоаннес Верморель
источник
возможный дубликат Как мне немного перевернуть в SQL Server?
Гильермо Гутьеррес

Ответы:

152

Используйте оператор ~:

DECLARE @MyBoolean bit
SET @MyBoolean = 0
SET @MyBoolean = ~@MyBoolean
SELECT @MyBoolean
Джонас Линкольн
источник
11
Это потому, что вы используете int, а не немного.
Джонас Линкольн
4
Столбец немного ... может ли иметь значение версия БД?
Мартин
Я знаю, что это работает в SQL Server 2008. Я делаю это все время. Вопрос касался SQL Server 2005, я не уверен, работает он там или нет.
Дэн Ван Винкль,
3
Исправление: Согласно MS, это должно работать и в 2005 году. Больше информации здесь .
Дэн Ван Винкль,
3
Хороший ответ, я только что протестировал его, и он отлично работает даже в SQL Server 2000.
Альберто Мартинес,
25

Ваше решение хорошее ... вы также можете использовать этот синтаксис для небольшого переключения в SQL ...

DECLARE @MyBoolean bit;
SET @MyBoolean = 0;
SET @MyBoolean = @MyBoolean ^ 1; 
SELECT @MyBoolean;
Гальский
источник
1
Просто для информации, это работает, потому что это побитовая эксклюзивная операция. То же, что и оператор XOR на многих языках. Это в основном то же самое, что и делать, SET @MyBoolean = 1 - @MyBooleanза исключением того, что здесь используется битовая математика, а не целочисленная. Несмотря на то, что это уместно и работает, это может сбивать с толку людей, не разбирающихся в математике. Больше информации здесь . @Jonas Линкольна решение лучше.
Дэн Ван Винкль,
1
К вашему сведению, это решение работает для вычисляемых полей, тогда как оператор case - нет. Благодаря!
anyeone
22

Вычитание значения из 1 выглядит так, как будто это поможет, но с точки зрения выражения намерения я бы предпочел:

SET @MyBoolean = CASE @MyBoolean WHEN 0 THEN 1 ELSE 0 END

Он более подробный, но я думаю, что его немного легче понять.

Мэтт Гамильтон
источник
10

Чтобы назначить инвертированный бит, вам нужно использовать побитовый оператор НЕ. При использовании побитового оператора НЕ, '~', вы должны убедиться, что ваш столбец или переменная объявлена ​​как бит.

Это не даст вам ноля:

Select ~1 

Это будет:

select ~convert(bit, 1)

Так будет это:

declare @t bit
set @t=1
select ~@t
Кулак ярости
источник
9

В SQL 2005 нет реального логического значения, битовое значение - это что-то другое.

Бит может иметь три состояния: 1, 0 и null (потому что это данные). SQL не преобразует их автоматически в истину или ложь (хотя, как ни странно, менеджер предприятия SQL это сделает)

Лучший способ представить битовые поля в логике - это целое число, равное 1 или 0.

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

Кит
источник
5

BIT - это числовой тип данных, а не логический. Вот почему к нему нельзя применять логические операторы.
SQL Server не имеет типа данных BOOLEAN (не уверен в SQL SERVER 2008), поэтому вам нужно придерживаться чего-то вроде решения @Matt Hamilton.

аку
источник
4

Используйте ABSдля получения абсолютного значения (-1 становится 1) ...

DECLARE @Trend AS BIT
SET @Trend = 0
SELECT @Trend, ABS(@Trend-1)
Стивен Б. Крейвер
источник
2
Вы пропустили объяснение, почему -1вообще могло возникнуть. То есть: не будет, если вычитание выражено в более логичной / интуитивной форме, которую использовал OP. Это бессмысленно загадочный и обходной способ сделать это.
underscore_d