2009-09-09 6 views
50

Ich versuche, ein Bitfeld in SQL Server mit einer Update-Abfrage zu spiegeln, das heißt, ich möchte alle 0 in 1 und umgekehrt machen. Was ist die eleganteste Lösung?Wie werden Bitfelder in T-SQL umgedreht?

Es scheint keinen bitweisen NOT-Operator in T-SQL zu geben (es sei denn, mir fehlt etwas Offensichtliches) und ich konnte keine andere Möglichkeit finden, das Update durchzuführen.

Antwort

91

Sie brauchen kein bitweises - nicht dafür - nur XOR es mit 1/true.

es zu prüfen:

update tableX 
set bitFieldY = bitFieldY^1 
where ... 

MSDN T-SQL Exclusive-OR (^)

+0

Großartig! Danke dafür - es funktioniert wie ein Zauber. Ich muss natürlich ein bisschen mehr darüber lernen, wie man binäre Operatoren verwendet. – Billious

+1

Ein anderer Artikel: http://blogs.lessthandot.com/index.php/DataMgmt/DBProgramming/MSSQLServer/how-to-flip-a-bit-in- sql-server-by-using –

+0

Denken Sie daran, dass 'bitFieldY^1' ein 'int' zurückgibt, also wenn Sie es wieder ein' bit' brauchen, 'CAST' oder' CONVERT' es zurück zu 'bit' . –

11

Ich war ziemlich sicher, dass die meisten SQL-Aromen ein bitweises NOT hatten, also überprüfte ich und dort tut appear to be one in TSQL.

Aus der Dokumentation ist das Zeichen ~.

+0

'NICHT VON MyTable' ist ein Syntaxfehler MyBitField SELECT. –

+2

SELECT ~ MyBitField von MyTable Mit anderen Worten Update MyTable Set MyBitField = ~ MyBitField –

10
UPDATE tblTest SET MyBitField = CASE WHEN MyBitField = 1 THEN 0 ELSE 1 END 

werden Es ist langweilig, aber jeder verstehen, was es tut:

select idColumn, bitFieldY, bitFieldY^1 as Toggled 
from tableX 

zu aktualisieren.

EDIT:

Sie könnten auch für NULL-Werte berücksichtigen müssen, wie in den Kommentaren vorgeschlagen. Hängt von Ihren Anforderungen natürlich ab.

UPDATE tblTest SET 
    MyBitField = CASE 
     WHEN MyBitField = 1 THEN 0 
     WHEN MyBitField = 0 THEN 1 
     ELSE NULL -- or 1 or 0 depending on requirements 
    END 
+0

Dies setzt MyBitField auf 1, wenn es als NULL startet. Nicht genau das bisschen kippen. –

+0

Ich dachte, es war offensichtlich ... aber ich werde Informationen über den Umgang mit Nullen nur für den Fall hinzufügen. – Mayo

+0

Ich würde eher mit einigen der anderen Jungs übereinstimmen und für die ~ oder die "^ 1" gehen. Vor allem, wenn dies eine einmalige Sache ist (scheint nur sauberer). Wenn es sich jedoch um etwas handelt, das eingehalten wird und Wartbarkeit besteht, ist diese Lösung sicherlich die einfachste. – LJM

0

Haben Sie das versucht?

UPDATE mytable SET somecolumn = 
    CASE WHEN somecolumn = 0 THEN 1 
     WHEN somecolumn IS NULL THEN NULL 
     WHEN somecolumn = 1 THEN 0 
    END 
40

Warum nicht ein einfaches bitfield = 1 - bitfield?

+0

Ein genialer und eleganter Ansatz, insbesondere für eine einmalige Abfrage, bei der die Lesbarkeit nicht wichtig ist. – Billious

+1

@Billious, und GBN Sie haben beide recht, aber ich denke, Austins Antwort ist gut genug, um das Ziel in seiner klaren Bedeutung zu verstehen. Das Umdrehen eines Bits mit 1-x wird die neuen Käufer verwirren und ist daher kein geeigneter Weg, dies zu erreichen. Ich stimme auch zu, dass es mehr als nur Ansätze geben wird, etwas zu tun, aber wenn es einen empfohlenen Weg dafür gibt, sollten wir damit gehen, was vermutlich schneller ist als ein nicht empfohlener Ansatz. – KMX

16

Ein anderer Weg ist

DECLARE @thebit bit = 1, @theflipbit bit 

SET @theflipbit = ~ @thebit 

SELECT @theflipbit 

wo "~" bedeutet "NOT" Operator. Es ist sauber und Sie erhalten einen guten Code zum Lesen. "Negieren Sie das Bit" ist noch sauberer und es tut genau, was der "NOT" Operator für entworfen wurde.

0

Abfrage (vb)

x = "select x from table" 

Update (vb)

"update table set x=" Not(x*(1))