Pergunta

Estou tentando criar uma visualização onde desejo que uma coluna seja apenas verdadeira ou falsa.No entanto, parece que não importa o que eu faça, o SQL Server (2008) acredita que minha coluna de bits pode de alguma forma ser nula.

Tenho uma tabela chamada "Produto" com a coluna "Status" que é INT, NULL.Em uma view, quero retornar uma linha para cada linha em Produto, com uma coluna BIT definida como verdadeira se a coluna Produto.Status for igual a 3, caso contrário o campo de bit deverá ser falso.

SQL de exemplo

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

Se eu salvar esta consulta como uma visualização e observar as colunas no Object Explorer, a coluna HasStatus será definida como BIT, NULL.Mas nunca deve ser NULL.Existe algum truque mágico de SQL que eu possa usar para forçar esta coluna a ser NOT NULL.

Observe que, se eu remover o CAST() em volta do CASE, a coluna está definida corretamente como NOT NULL, mas o tipo da coluna é definido como INT, que não é o que eu quero.Eu quero que seja BIT. :-)

Foi útil?

Solução

Você pode conseguir o que deseja reorganizar um pouco sua consulta. O truque é que o ISNULL tem que estar do lado de fora antes que o SQL Server entenderá que o valor resultante nunca pode ser NULL.

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

Uma razão pela qual eu realmente acho isso útil é quando usar um Orm E você não deseja o valor resultante mapeado para um tipo anulável. Pode facilitar as coisas se o seu aplicativo vê o valor como nunca sendo nulo. Então você não precisa escrever código para lidar com exceções nulas, etc.

Outras dicas

Para sua informação, para as pessoas que se deparam com esta mensagem, adicionar ISNULL() na parte externa do elenco/conversão pode atrapalhar o otimizador em sua visualização.

Tínhamos 2 tabelas usando o mesmo valor como chave de índice, mas com tipos de precisão numérica diferentes (ruim, eu sei) e nossa visão era uni-las para produzir o resultado final.Mas nosso código de middleware estava procurando por um tipo de dados específico, e a visualização tinha um CONVERT() ao redor da coluna retornada

Percebi, assim como o OP, que os descritores de coluna do resultado da visualização o definiram como anulável e pensei que é uma chave primária/estrangeira em 2 tabelas;por que quereríamos o resultado definido como anulável?

Encontrei este post, joguei ISNULL() em volta da coluna e pronto - não é mais anulável.

O problema foi que o desempenho da visualização foi por água abaixo quando uma consulta foi filtrada naquela coluna.

Por alguma razão, um CONVERT() explícito na coluna de resultados da visualização não estragou o otimizador (ele teria que fazer isso de qualquer maneira por causa das diferentes precisões), mas adicionar um wrapper ISNULL() redundante sim, em um grande caminho.

Tudo o que você pode fazer em uma instrução SELECT é controlar os dados que o mecanismo de banco de dados envia como cliente. A instrução SELECT não tem efeito na estrutura da tabela subjacente. Para modificar a estrutura da tabela, você precisa executar uma instrução ALTER TABLE.

  1. Primeiro, certifique -se de que atualmente não há nulos nesse campo de bits na tabela
  2. Em seguida, execute a seguinte instrução DDL: Alter Table dbo.Product Alter column status bit not null

Se, otoh, tudo o que você está tentando fazer é controlar a saída da visualização, então o que você está fazendo é suficiente. Sua sintaxe garantirá que a saída da coluna Hasstatus no Views ResultSet Nunca seja nulo. Será sempre Seja um valor de bit = 1 ou valor de bit = 0. Não se preocupe com o que o explorador de objeto diz ...

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top