Eu tenho uma tabela, com Id
como chave primária.
create table Anything
(
Id bigint not null primary key identity(1, 1)
)
Quando olho para esta tabela em Object Explorer
, vejo esta imagem, claro:
Como você pode ver, a coluna não Id
é null .
Então eu crio uma visão fictícia nesta tabela fictícia:
create view IdIsTwoView
as
select
Id,
(
case
when Id = 2
then cast(1 as bit)
else cast(0 as bit)
end
) as IdIsTwo
from Anything
Mas desta vez, no Object Explorer, vejo este resultado:
Como você pode ver, apesar de minha case
cláusula ser abrangente e cobrir 100% de todos os registros, e ter uma resposta para todos os registros, ela é anulável.
Por que o SQL Server tem esse comportamento estranho? E como forçá-lo a não ser nulo ?
PS temos uma infraestrutura para gerar código dinamicamente, e esse comportamento nos causa problemas e temos que ir manualmente e alterar todos os bool?
tipos em C# para bool
.
Para responder a parte do porquê da sua pergunta, a
CASE
expressão result é anulável porque oCAST
resultado da função é anulável. Isso pode ser observado com:Resultado (abreviado):
O resultado não é nulo quando uma constante é especificada sem a função:
Mas o tipo de dados do resultado é
int
em vez do desejadobit
, pois o SQL Server não possuibit
constante sem conversão implícita ou explícita,ISNULL
é necessário coagir um resultado não nulo como @MichaelGreen respondeu.Para responder à sua pergunta real - não tenho ideia. Meu palpite é que o analisador pode examinar colunas diretamente para determinar a nulidade. Se houver algo entre a referência de coluna e a saída - como uma função ou uma expressão - que possa afetar a nulidade, a saída será considerada anulável. A MS simplesmente não escreveu um código para examinar todas as circunstâncias em profundidade e raciocinar sobre os resultados. Eles também têm orçamentos, cronogramas e pendências como todos os outros. Isso simplesmente não tem prioridade.
Essa hipótese me fez pensar, no entanto. Se ele pode interpretar colunas, sobre quais construções ele pode raciocinar? Se eu pudesse oferecer uma expressão suficientemente simples que garantisse não ser nula, ela produziria a saída desejada. A resposta é sim, com ISNULL :
Eu escolhi -1 para o valor de substituição, pois está fora do intervalo da identidade, portanto, será um erro óbvio se for visto. Qualquer constante funcionaria, eu acho.