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?

Joannes Vermorel
źródło
możliwy duplikat Jak mogę odwrócić trochę w SQL Server?
Guillermo Gutiérrez

Odpowiedzi:

152

Użyj operatora ~:

DECLARE @MyBoolean bit
SET @MyBoolean = 0
SET @MyBoolean = ~@MyBoolean
SELECT @MyBoolean
Jonas Lincoln
źródło
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;
Galwegian
źródło
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.

Matt Hamilton
źródło
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
Pięść furii
źródło
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.

Keith
źródło
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.

aku
źródło
4

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

DECLARE @Trend AS BIT
SET @Trend = 0
SELECT @Trend, ABS(@Trend-1)
Stephen B. Craver
źródło
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