¿El 'NO' booleano en T-SQL no funciona en el tipo de datos 'bit'?

81

Al intentar realizar una única operación NOT booleana, parece que en MS SQL Server 2005, el siguiente bloque no funciona

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

En cambio, estoy teniendo más éxito con

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

Sin embargo, esto parece una forma un poco retorcida de expresar algo tan simple como una negación.

¿Me estoy perdiendo de algo?

Joannes Vermorel
fuente
posible duplicado de ¿Cómo cambio un poco en SQL Server?
Guillermo Gutiérrez

Respuestas:

151

Utilice el operador ~:

DECLARE @MyBoolean bit
SET @MyBoolean = 0
SET @MyBoolean = ~@MyBoolean
SELECT @MyBoolean
Jonas Lincoln
fuente
11
Es porque estás usando un int, no un poco.
Jonas Lincoln
4
La columna es un poco ... ¿podría importar la versión de DB?
Martin
Sé que esto funciona en SQL Server 2008. Hago esto todo el tiempo. La pregunta era para SQL Server 2005, que no estoy seguro de si funciona allí o no.
Dan VanWinkle
3
Corrección: Según MS, esto también debería funcionar en 2005. Más info aquí .
Dan VanWinkle
3
Buena respuesta, acabo de probarlo y funciona bien, incluso en SQL Server 2000.
Alberto Martinez
25

Su solución es buena ... también puede usar esta sintaxis para alternar un poco en SQL ...

DECLARE @MyBoolean bit;
SET @MyBoolean = 0;
SET @MyBoolean = @MyBoolean ^ 1; 
SELECT @MyBoolean;
Galwegian
fuente
1
Solo para un FYI, esto funciona porque es una operación exclusiva bit a bit. Igual que el operador XOR en muchos idiomas. Esto es básicamente lo mismo que hacer, SET @MyBoolean = 1 - @MyBooleanexcepto que usa matemáticas de bits en lugar de matemáticas enteras. Aunque esto es apropiado y funciona, puede resultar confuso para las personas que no entienden las matemáticas básicas. Más info aquí . La solución de @Jonas Lincoln es mejor.
Dan VanWinkle
1
Como un FYI, esta solución funciona para campos calculados, mientras que una declaración de caso no. ¡Gracias!
anyeone
22

Restar el valor de 1 parece que funcionará, pero en términos de expresar la intención, creo que prefiero ir con:

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

Es más detallado, pero creo que es un poco más fácil de entender.

Matt Hamilton
fuente
10

Para asignar un bit invertido, necesitará utilizar el operador NOT a nivel de bit. Cuando utilice el operador NOT bit a bit, '~', debe asegurarse de que su columna o variable se declare como bit.

Esto no te dará cero:

Select ~1 

Esta voluntad:

select ~convert(bit, 1)

Entonces esto:

declare @t bit
set @t=1
select ~@t
Puño de la furia
fuente
9

En SQL 2005 no hay un valor booleano real, el valor de bit es realmente algo más.

Un bit puede tener tres estados, 1, 0 y nulo (porque son datos). SQL no los convierte automáticamente en verdadero o falso (aunque, confusamente, el administrador empresarial de SQL lo hará)

La mejor forma de pensar en los campos de bits en lógica es como un número entero que es 1 o 0.

Si usa la lógica directamente en un campo de bits, se comportará como cualquier otra variable de valor, es decir, la lógica será verdadera si tiene un valor (cualquier valor) y falsa en caso contrario.

Keith
fuente
5

BIT es un tipo de datos numérico, no booleano. Es por eso que no puede aplicarle operadores booleanos.
SQL Server no tiene el tipo de datos BOOLEAN (no estoy seguro de SQL SERVER 2008) por lo que debe seguir con algo como la solución de @Matt Hamilton.

aku
fuente
4

Use ABSpara obtener el valor absoluto (-1 se convierte en 1) ...

DECLARE @Trend AS BIT
SET @Trend = 0
SELECT @Trend, ABS(@Trend-1)
Stephen B. Craver
fuente
2
Te perdiste explicar por qué -1surgiría alguna vez en primer lugar. Es decir: no lo hará, si la resta se expresa en la forma más lógica / intuitiva que utilizó el OP. Esta es una forma inútil y críptica de hacerlo.
underscore_d