Encerrando temporariamente este assunto sobre nulls(aqui e aqui), venho mostrar como podemos tratar inconsistências do banco interagindo com a linguagem T-SQL quando o assunto é valor nulo (NULL).

No post anterior vimos que nulls não possuem uma distinção clara do que é aplicável e não aplicável (Missing and applicable e inapplicable) ele apenas entende que ali falta um valor e que esse valor é desconhecido.

Por esse pequeno problema, temos diversas inconsistências em resultados e execuções de query, como foi o caso do join, por exemplo.

Agora, vamos ver como e quais são estas inconsistências tratadas dentro do SQL Server com funções de agregações, views e até mesmo com merge.

Inconsistências dos nulls com agregações

A linguagem SQL de um modo geral permite duas formas de agregação: por coluna sum(col1) ou por linha count(*). Até aqui, está tudo ok, não há o menor problema e já conhecemos o seu comportamento; A questão que quando passa a envolver null o comportamento do banco quanto a query muda e é aí que se iniciam as inconsistências.

Veja o bloco de comando abaixo, crie e execute a soma entre as três colunas.

Como a coluna três tem o valor nulo, todo o resultado assim o é, como podemos ver na imagem.

Mesmo que execute uma query que faça um sum para cada coluna, o resultado não muda, visto que só há uma linha para cada. A função sum só permite um argumento e mais, a col3 continuará retornando null.

Somente a função count que retorna um valor palpável, como vimos no exemplo acima, ainda que estas ignorem nulls quando executadas em uma coluna que possui mais de 1 linha. Veja:

Outro ponto que é importante destacar é que o próprio SQL Server informa que a função de agregação está excluindo valores nulos da consulta.

Agora perceba o seguinte: quando executamos uma query que calcula a média de uma coluna ou executamos o count nela, o null é completamente ignorado. Sabemos que a média é a soma dos valores / pela sua quatidade de linhas – aqui foram duas. Mesmo existindo três!

Vimos algumas das pequenas inconsistências que podem ocorrer quando tratamos null utilizando funções de agregação principalmente com count e outras de operações. Agora, vamos observar como o SQL Server se comporta quando utilizamos as funções de filtro e comparação: ON, HAVING E WHERE.

Em posts anteriores vimos que estas cláusulas quando utilizadas costumar ‘pensar’ com base em três valores lógicos: true, false e unknown – rejeitando falso e desconhecido.

Nos exemplos a seguir, vamos analisar este comportamento com maior detalhe.

Primeiro crie a tabela Contact com uma restrição que proíbe inserção de horas negativas, insira os 3 valores e execute um select.

Após, faça um novo teste de insert e perceba que a última linha irá falhar por quebrar a restrição.

Podemos perceber que a constraint criada está funcionando corretamente, permitindo null mas proibindo valores negativos na tabela. Agora veja como a opção de check se comporta quando criamos uma view. Lembrando que a view adota as mesmas configurações das tabelas ao qual ela pertence, logo, a coluna HourlyRate permite null.

O insert falha, mesmo a coluna permitindo null!

Isso acontece porque o check option na view, ainda que seja um check, ele foi desenhado para agir como um filtro. Quando o check option age desta forma, ignora valores falsos e desconhecidos, diferente do check constraint.

Uma forma de solucionar e inserir, é da seguinte maneira:

Pense que a opção check constraint aceita valores desconhecidos e a check option não.

Se quiser alterar a view para que nulls sejam inseridos, basta criar a view desta forma.

Então, tenham cuidado quando forem utilizar a função de check em seus ambientes ou estudos pois variando da situação, o comportamento dele quanto a query pode ser diferente!

NULLS COM IF/WHILE/CASE

Sabendo que estes três elementos trabalham com predicados de qualificação analisando de forma direta o seguinte: “se for verdade, ação A se não, ação B.Fim”

Dentre as três funções while é o único que avalia sua ação somente como verdade, ou seja, não há uma ação para caso seja ‘falso’.

Neste simples exemplo, veja o comportamento do case quando há uma variável com null, veja o resultado.

Com merge há uma forma de lidar com os três valores lógicos que permite em uma única declaração, criar ações para os três tipos, veja abaixo.

Primeiro crie a tabela T3, insira alguns dados e execute um select.

Agora, vamos executar o merge e com isso atualizar ou inserir na tabela t3. Ira depender da quantidade de match que o comando realizará.

Assim temos um comando merge que trata de valores desconhecidos, bastando apenas adicionar not matched by source.

CONCLUSÃO

Com este post finalizamos por hora o assunto NULL.

A intenção deste post foi complementar o outro que tratava sobre inconsistências quando temos este tipo de valor, mas abrangendo as funções de agregação.

Além, observamos que até nas operações de merge temos ferramentas de tratamento para operar com valores desconhecidos.

Null pode ser um problema se não houver um cuidado adequado quando for elaborar uma query para buscar dados no banco. Como vimos em posts anteriores, podem causar diferença nos resultados e se este resultado for um relatório, este será inconsistente e falho em entregar o valor desejado.

Link para o script!

Espero que gostem, saúde