Логічне "НЕ" у 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;

Проте це виглядає дещо звивистим способом висловити щось таке просте, як заперечення.

Мені чогось не вистачає?


Відповіді:


152

Використовуйте оператор ~:

DECLARE @MyBoolean bit
SET @MyBoolean = 0
SET @MyBoolean = ~@MyBoolean
SELECT @MyBoolean

11
Це тому, що ви використовуєте int, а не трохи.
Jonas Lincoln

4
Стовпець трохи ... чи може мати значення версія БД?
Мартін

Я знаю, що це працює в SQL Server 2008. Я роблю це постійно. Питання було щодо SQL Server 2005, і я не впевнений, працює він там чи ні.
Dan VanWinkle

3
Виправлення: За твердженням РС, це має спрацювати і в 2005 році. Більше інформації тут .
Dan VanWinkle

3
Приємна відповідь, я щойно перевірив і працює нормально, навіть у SQL Server 2000.
Альберто Мартінес

25

Ваше рішення є хорошим ... Ви також можете використовувати цей синтаксис, щоб трохи перемикати в SQL ...

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

1
Тільки для FYI це працює, оскільки це побітова ексклюзивна робота. Те саме, що оператор XOR у багатьох мовах. Це в основному те саме, що і робити, SET @MyBoolean = 1 - @MyBooleanза винятком того, що використовується бітова математика, а не ціла математика. Хоча це доречно і працює, це може заплутати людей, які не розуміють трохи математики. Більше інформації тут . @Jonas Лінкольна рішення краще.
Dan VanWinkle

1
Як FYI це рішення працює для обчислюваних полів, тоді як випадок справи - ні. Дякую!
хто,

22

Віднімання значення з 1 виглядає так, ніби це зробить трюк, але з точки зору вираження наміру я вважаю за краще:

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

Це більш багатослівно, але я думаю, це трохи легше зрозуміти.


10

Щоб призначити інвертований біт, вам потрібно буде використовувати побітове оператор NOT. При використанні побітового оператора NOT, '~', ви повинні переконатися, що ваш стовпець або змінна оголошені як біт.

Це не дасть вам нуля:

Select ~1 

Це буде:

select ~convert(bit, 1)

Так і це:

declare @t bit
set @t=1
select ~@t

9

У SQL 2005 немає реального булевого значення, бітове значення - це щось інше насправді.

Біт може мати три стани, 1, 0 і null (оскільки це дані). SQL автоматично не перетворює їх на істинні або хибні (хоча, що заплутано, менеджер підприємства SQL буде)

Найкращий спосіб розглядати бітові поля в логіці - це ціле число, яке дорівнює 1 або 0.

Якщо ви використовуєте логіку безпосередньо в розрядному полі, вона буде поводитися як будь-яка інша змінна значення - тобто логіка буде істинною, якщо вона має значення (будь-яке значення), а в іншому випадку - false.


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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.