Pregunta

Estoy intentando crear una vista en la que quiero que una columna sea solo verdadera o falsa.Sin embargo, parece que no importa lo que haga, SQL Server (2008) cree que mi columna de bits puede de alguna manera ser nula.

Tengo una tabla llamada "Producto" con la columna "Estado" que es INT, NULL.En una vista, quiero devolver una fila para cada fila en Producto, con una columna BIT establecida en verdadero si la columna Producto.Estado es igual a 3; de lo contrario, el campo de bits debería ser falso.

Ejemplo de SQL

SELECT CAST( CASE ISNULL(Status, 0)  
               WHEN 3 THEN 1  
               ELSE 0  
             END AS bit) AS HasStatus  
FROM dbo.Product  

Si guardo esta consulta como una vista y miro las columnas en el Explorador de objetos, la columna HasStatus se establece en BIT, NULL.Pero nunca debería ser NULL.¿Existe algún truco mágico de SQL que pueda usar para forzar que esta columna sea NOT NULL.

Observe que, si elimino el CAST() alrededor de CASE, la columna está configurada correctamente como NOT NULL, pero luego el tipo de columna se establece en INT, que no es lo que quiero.quiero que sea BIT. :-)

¿Fue útil?

Solución

Se puede lograr lo que quiere por re-organización de la consulta un poco. El truco es que el ISNULL tiene que estar en el exterior antes de SQL Server entenderá que el valor resultante no puede ser nunca NULL.

SELECT ISNULL(CAST(
    CASE Status
        WHEN 3 THEN 1  
        ELSE 0  
    END AS bit), 0) AS HasStatus  
FROM dbo.Product  

Una de las razones de hecho Me parece útil es cuando se utiliza una ORM y no lo hace quiere que el valor resultante asignada a un tipo anulable. Se puede facilitar las cosas a su alrededor si su aplicación ve el valor como nunca siendo posiblemente nula. Entonces usted no tiene que escribir el código de excepciones nulos mango, etc.

Otros consejos

Para su información, para las personas que se encuentran con este mensaje, agregar ISNULL() alrededor del exterior de la conversión/transmisión puede estropear el optimizador en su vista.

Teníamos 2 tablas que usaban el mismo valor como clave de índice pero con tipos de precisión numérica diferente (mala, lo sé) y nuestra vista se unía a ellas para producir el resultado final.Pero nuestro código de middleware buscaba un tipo de datos específico y la vista tenía un CONVERT() alrededor de la columna devuelta.

Noté, como lo hizo el OP, que los descriptores de columna del resultado de la vista lo definían como anulable y estaba pensando Es una clave primaria/externa en 2 tablas;¿Por qué querríamos que el resultado se definiera como anulable?

Encontré esta publicación, lancé ISNULL() alrededor de la columna y listo, ya no se pueden anular.

El problema fue que el rendimiento de la vista se fue por el retrete cuando se filtró una consulta en esa columna.

Por alguna razón, un CONVERT() explícito en la columna de resultados de la vista no arruinó el optimizador (tendría que hacerlo de todos modos debido a las diferentes precisiones), pero agregar un contenedor ISNULL() redundante sí lo hizo, en gran medida. forma.

Todo lo que se puede hacer en una instrucción Select es el control de los datos que el motor de base de datos envía a usted como cliente. La instrucción de selección no tiene efecto sobre la estructura de la tabla subyacente. Para modificar la estructura de la tabla es necesario ejecutar una sentencia ALTER TABLE.

  1. En primer lugar asegúrese de que actualmente no existen valores nulos en ese campo de bits en la tabla
  2. A continuación, ejecute la siguiente instrucción DDL:  Alter Table dbo.Product Alter column status bit not null

Si, Otoh, todo lo que está tratando de hacer es controlar la salida de la vista, entonces lo que está haciendo es suficiente. Su sintaxis se garantiza que la salida de la columna de HasStatus en el conjunto de resultados vistas, de hecho, no ser nulo. Será siempre ser de valor del bit de valor = 1 o el bit = 0. No se preocupe lo que el explorador de objetos dice ...

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top