Wartość logiczna „NIE” w T-SQL nie działa na typie danych „bit”?


82

Próbując wykonać pojedynczą operację logiczną NOT, wygląda na to, że pod MS SQL Server 2005 następujący blok nie działa

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

Zamiast tego odnoszę większe sukcesy z

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

Wygląda to jednak na nieco pokręcony sposób wyrażenia czegoś tak prostego jak zaprzeczenie.

Czy coś mi brakuje?


Odpowiedzi:


152

Użyj operatora ~:

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

11
To dlatego, że używasz int, a nie trochę.
Jonas Lincoln,

4
Kolumna jest trochę ... czy wersja DB może mieć znaczenie?
Martin

Wiem, że to działa w SQL Server 2008. Robię to cały czas. Pytanie dotyczyło programu SQL Server 2005, którego nie jestem pewien, czy działa, czy nie.
Dan VanWinkle

3
Korekta: według MS powinno to działać również w 2005 roku. Więcej informacji tutaj .
Dan VanWinkle,

3
Nicea odpowiedź, po prostu przetestowane i działa dobrze, nawet w SQL Server 2000
Alberto Martinez

25

Twoje rozwiązanie jest dobre ... możesz również użyć tej składni, aby przełączyć się trochę w SQL ...

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

1
Tylko dla FYI działa to, ponieważ jest to operacja bitowa na wyłączność. To samo, co operator XOR w wielu językach. Zasadniczo jest to to samo, co robienie, SET @MyBoolean = 1 - @MyBooleanz tym wyjątkiem, że używa się matematyki bitowej zamiast matematyki całkowitej. Mimo że jest to właściwe i działa, może być mylące dla osób, które nie rozumieją matematyki bitowej. Więcej informacji tutaj . @Jonas Lincolna rozwiązanie jest lepsze.
Dan VanWinkle

1
Jako informacja do Twojej wiadomości to rozwiązanie działa dla pól obliczeniowych, podczas gdy instrukcja przypadku nie działa. Dzięki!
anyeone

22

Odejmowanie wartości od 1 wygląda na to, że załatwi sprawę, ale jeśli chodzi o wyrażanie zamiaru, myślę, że wolałbym:

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

Jest bardziej szczegółowy, ale myślę, że jest trochę łatwiejszy do zrozumienia.


10

Aby przypisać odwrócony bit, musisz użyć operatora bitowego NOT. Używając bitowego operatora NOT, '~', musisz upewnić się, że twoja kolumna lub zmienna jest zadeklarowana jako bit.

To nie da Ci zera:

Select ~1 

To będzie:

select ~convert(bit, 1)

Więc to:

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

9

W SQL 2005 nie ma prawdziwej wartości logicznej, wartość bitowa jest naprawdę czymś innym.

Bit może mieć trzy stany, 1, 0 i null (ponieważ to dane). SQL nie konwertuje ich automatycznie na prawdę lub fałsz (chociaż, myląco, SQL Enterprise Manager to zrobi)

Najlepszym sposobem myślenia o polach bitowych w logice jest liczba całkowita równa 1 lub 0.

Jeśli użyjesz logiki bezpośrednio na polu bitowym, będzie zachowywać się jak każda inna zmienna wartości - tj. Logika będzie prawdziwa, jeśli ma wartość (dowolną wartość), a fałsz w przeciwnym razie.


5

BIT to numeryczny typ danych, a nie wartość logiczna. Dlatego nie możesz zastosować do niego operatorów logicznych.
SQL Server nie ma typu danych BOOLEAN (nie jestem pewien co do SQL SERVER 2008), więc musisz trzymać się czegoś takiego jak rozwiązanie @Matt Hamilton.


4

Użyj, ABSaby uzyskać wartość bezwzględną (-1 staje się 1) ...

DECLARE @Trend AS BIT
SET @Trend = 0
SELECT @Trend, ABS(@Trend-1)

2
Przegapiłeś wyjaśnienie, dlaczego w -1ogóle miałoby się pojawić. To znaczy: nie będzie, jeśli odejmowanie jest wyrażone w bardziej logicznej / intuicyjnej formie, której używał OP. Jest to bezcelowo tajemniczy i okrężny sposób, aby to zrobić.
underscore_d
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.