2008-10-07 3 views
64

Essayer d'effectuer un booléen unique NOT opération, il apparaît que sous MS SQL Server 2005, le bloc suivant ne fonctionne pasBoolean 'NOT' dans T-SQL ne fonctionne pas sur le type de données 'bit'?

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

Au lieu de cela, je reçois plus de succès avec

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

Pourtant, Cela ressemble un peu à une façon tordue d'exprimer quelque chose d'aussi simple qu'une négation.

Ai-je raté quelque chose?

+0

double possible de [Comment puis-je flippe un peu en SQL Server?] (Http://stackoverflow.com/questions/171173/how-do-i-flip-a-bit-in-sql-server) –

Répondre

130

Utilisez l'opérateur ~:

DECLARE @MyBoolean bit 
SET @MyBoolean = 0 
SET @MyBoolean = [email protected] 
SELECT @MyBoolean 
+1

Cela n'a pas fonctionné. Il a tourné 0 en -1, et 1 en -2. – Martin

+8

C'est parce que vous utilisez un int, pas un peu. –

+3

La colonne est un peu ... la version DB pourrait-elle être importante? – Martin

24

Votre solution est un bon ... vous pouvez également utiliser cette syntaxe pour passer un peu dans SQL ...

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

Cette solution a fonctionné ... merci. – Martin

+0

Juste pour un FYI, cela fonctionne parce que le fonctionnement exclusif au niveau du bit. Identique à l'opérateur XOR dans de nombreuses langues. C'est fondamentalement la même chose que de faire SET @MyBoolean = 1 - @ MyBoolean', sauf qu'il utilise des maths de bits plutôt que des maths entiers. Même si cela est approprié et fonctionne, il peut être source de confusion pour les gens qui ne comprennent pas les mathématiques. Plus d'informations [ici] (http://msdn.microsoft.com/en-us/library/ms176122.aspx). @ Jonas Lincoln [solution] (http://stackoverflow.com/questions/177762/boolean-not-in-t-sql-not-working-on-bit-datatype#answer-177893) est mieux. –

+0

En tant que FYI, cette solution fonctionne pour les champs calculés, contrairement à une déclaration de cas. Merci! – anyeone

4

BIT est un type de données numérique, non booléen. C'est pourquoi vous ne pouvez pas lui appliquer d'opérateurs booléens.
SQL Server n'a pas de type de données BOOLEAN (vous n'êtes pas sûr de SQL SERVER 2008), vous devez donc vous en tenir à quelque chose comme la solution de @Matt Hamilton.

20

Soustraire la valeur de 1 ressemble à ça va faire l'affaire, mais en termes d'intention d'exprimer, je pense que je préfère aller avec:

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

Il est plus bavard, mais je pense qu'il est un peu plus facile à comprendre.

8

Dans SQL 2005 il n'y a pas une réelle valeur booléenne, la valeur du bit est vraiment quelque chose d'autre.

Un bit peut avoir trois états, 1, 0 et null (parce que c'est une donnée). SQL ne convertit pas automatiquement ceux-ci à vrai ou faux (bien que, confusément gestionnaire SQL Enterprise)

La meilleure façon de penser des champs de bits dans la logique est un entier qui est 1 ou 0.

Si vous utilisez logique directement sur un champ de bits, il se comportera comme n'importe quelle autre variable de valeur - c'est-à-dire que la logique sera vraie si elle a une valeur (n'importe quelle valeur) et false sinon.

2

Utilisez ABS pour obtenir la valeur absolue (-1 devient 1) ...

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

Vous avez manqué d'expliquer pourquoi «-1» se poserait en premier lieu. C'est-à-dire: ce ne sera pas le cas si la soustraction est exprimée sous la forme la plus logique/intuitive que le PO a utilisée. C'est un moyen inutilement cryptique et rond de le faire. –

7

Pour attribuer un bit inversé, vous devez utiliser le bit opérateur NOT. Lorsque vous utilisez l'opérateur NOTwise, '~', vous devez vous assurer que votre colonne ou variable est déclarée comme un bit.

Cela ne vous donnera pas zéro:

Select ~1 

Ce sera:

select ~convert(bit, 1) 

Il en sera ceci:

declare @t bit 
set @t=1 
select [email protected] 
Questions connexes