Boolesches 'NOT' in T-SQL funktioniert nicht mit 'Bit'-Datentyp?

81

Beim Versuch, eine einzelne boolesche NOT-Operation auszuführen, scheint der folgende Block unter MS SQL Server 2005 nicht zu funktionieren

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

Stattdessen werde ich erfolgreicher mit

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

Dies scheint jedoch eine verdrehte Art zu sein, etwas so Einfaches wie eine Negation auszudrücken.

Vermisse ich etwas

Joannes Vermorel
quelle
Mögliches Duplikat von Wie kann ich in SQL Server ein bisschen umdrehen?
Guillermo Gutiérrez

Antworten:

151

Verwenden Sie den Operator ~:

DECLARE @MyBoolean bit
SET @MyBoolean = 0
SET @MyBoolean = ~@MyBoolean
SELECT @MyBoolean
Jonas Lincoln
quelle
11
Es ist, weil Sie ein int verwenden, nicht ein bisschen.
Jonas Lincoln
4
Spalte ist ein bisschen ... könnte die DB-Version eine Rolle spielen?
Martin
Ich weiß, dass dies in SQL Server 2008 funktioniert. Ich mache das die ganze Zeit. Die Frage war für SQL Server 2005, bei dem ich nicht sicher bin, ob es dort funktioniert oder nicht.
Dan VanWinkle
3
Korrektur: Laut MS sollte dies auch 2005 funktionieren. Mehr Infos hier .
Dan VanWinkle
3
Schöne Antwort, ich habe es gerade getestet und funktioniert auch in SQL Server 2000.
Alberto Martinez
25

Ihre Lösung ist gut ... Sie können diese Syntax auch verwenden, um ein wenig in SQL umzuschalten ...

DECLARE @MyBoolean bit;
SET @MyBoolean = 0;
SET @MyBoolean = @MyBoolean ^ 1; 
SELECT @MyBoolean;
Galwegisch
quelle
1
Nur für eine FYI funktioniert dies, weil es bitweise exklusive Operation ist. Entspricht dem XOR-Operator in vielen Sprachen. Dies ist im Grunde dasselbe wie das Tun, SET @MyBoolean = 1 - @MyBooleanaußer dass Bitmathematik anstelle von Ganzzahlmathematik verwendet wird. Obwohl dies angemessen ist und funktioniert, kann es für Leute, die Bitmathematik nicht verstehen, verwirrend sein. Mehr Infos hier . @ Jonas Lincolns Lösung ist besser.
Dan VanWinkle
1
Als FYI funktioniert diese Lösung für berechnete Felder, eine case-Anweisung jedoch nicht. Vielen Dank!
Jeder
22

Das Subtrahieren des Werts von 1 scheint den Trick zu tun, aber in Bezug auf das Ausdrücken von Absichten denke ich, dass ich es vorziehen würde, Folgendes zu tun:

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

Es ist ausführlicher, aber ich denke, es ist etwas einfacher zu verstehen.

Matt Hamilton
quelle
10

Um ein invertiertes Bit zuzuweisen, müssen Sie den bitweisen NOT-Operator verwenden. Wenn Sie den bitweisen NOT-Operator '~' verwenden, müssen Sie sicherstellen, dass Ihre Spalte oder Variable als Bit deklariert ist.

Dies gibt Ihnen keine Null:

Select ~1 

Dieser Wille:

select ~convert(bit, 1)

So wird dies:

declare @t bit
set @t=1
select ~@t
Faust der Wut
quelle
9

In SQL 2005 gibt es keinen echten booleschen Wert, der Bitwert ist wirklich etwas anderes.

Ein Bit kann drei Zustände haben, 1, 0 und null (weil es Daten sind). SQL konvertiert diese nicht automatisch in true oder false (obwohl dies verwirrenderweise der SQL Enterprise Manager tut).

Bitfelder in der Logik lassen sich am besten als Ganzzahl 1 oder 0 betrachten.

Wenn Sie Logik direkt für ein Bitfeld verwenden, verhält sie sich wie jede andere Wertvariable - dh die Logik ist wahr, wenn sie einen Wert (einen beliebigen Wert) hat, und andernfalls falsch.

Keith
quelle
5

BIT ist ein numerischer Datentyp, kein Boolescher. Aus diesem Grund können Sie keine booleschen Operatoren darauf anwenden.
SQL Server hat keinen BOOLEAN-Datentyp (nicht sicher über SQL SERVER 2008), daher müssen Sie sich an die Lösung von @Matt Hamilton halten.

aku
quelle
4

Verwenden Sie ABS, um den absoluten Wert zu erhalten (-1 wird 1) ...

DECLARE @Trend AS BIT
SET @Trend = 0
SELECT @Trend, ABS(@Trend-1)
Stephen B. Craver
quelle
2
Sie haben es versäumt zu erklären, warum -1überhaupt etwas entstehen würde. Das heißt: Es wird nicht, wenn die Subtraktion in der logischeren / intuitiveren Form ausgedrückt wird, die das OP verwendet hat. Dies ist eine sinnlose kryptische und umfassende Möglichkeit, dies zu tun.
underscore_d