Craig Mullins | April 6, 2015
Um nulo representa informações ausentes ou desconhecidas no nível da coluna.
Se uma coluna "valor" puder ser nula, pode significar uma de duas coisas:
o atributo não é aplicável a determinadas ocorrências da entidade ou o atributo se aplica a todas as ocorrências da entidade, mas as informações nem sempre
são conhecidas. Obviamente, também poderia ser uma combinação dessas duas situações.
Um nulo não é igual a 0 ou em branco.
Nulo significa que nenhuma entrada foi feita para a coluna e implica que o valor é desconhecido ou não aplicável.
Como o DB2 suporta nulo, é possível distinguir entre uma entrada deliberada de 0 (para colunas numéricas) ou um espaço em branco (para colunas de caracteres)
e uma entrada desconhecida ou inaplicável (NULL para colunas numéricas e de caracteres).
Nulo indica que o usuário não fez uma entrada explicitamente ou inseriu NULL explicitamente para a coluna.
Por exemplo, um valor nulo na coluna Preço da tabela ITEM em algum banco de dados não significa que o item está sendo distribuído gratuitamente; em vez disso,
significa que o preço não é conhecido ou ainda não foi definido.
Às vezes, os nulos são inadequadamente referidos como "valores nulos".
O uso do termo value para descrever um nulo é impreciso porque um nulo implica a falta de um valor.
Portanto, basta usar o termo nulo ou nulos (sem anexar o termo "valor" ou "valores" a ele).
Alguns exemplos
Quando os nulos são úteis?
Bem, definir uma coluna como NULL fornece um espaço reservado para dados que você talvez ainda não conheça.
Por exemplo, quando um novo funcionário é contratado e inserido na tabela EMP, como deve ser definida a coluna de data de término do funcionário?
Não sei você, mas não quero que nenhuma data válida seja definida nessa coluna para o meu registro de funcionário.
Em vez disso, null pode ser usado para especificar que a data de término é atualmente desconhecida.
Vamos considerar outro exemplo.
Suponha que também capturamos a cor do cabelo dos funcionários quando eles são contratados.
Considere três ocorrências potenciais de entidade:
um homem com cabelo preto, uma mulher com cor de cabelo desconhecida e um homem careca.
A mulher com a cor do cabelo desconhecida e o careca podem ser atribuídos como nulos, mas por razões diferentes.
A cor do cabelo da mulher seria nula, significando atualmente desconhecida; a cor do cabelo do careca também pode ser nula, neste caso, significando não aplicável.
Como você pode lidar com isso sem usar valores nulos?
Você precisaria criar valores especiais para a coluna HairColor que significassem "careca" e "desconhecida".
Isso é possível para uma coluna CHAR como HairColor, mas e uma coluna DB2 DATE?
Todas as ocorrências de uma coluna atribuída como um tipo de dados DATE são datas válidas.
Talvez não seja possível usar um valor de data especial para significar "desconhecido".
É aqui que o uso de nulos é mais prático.
O DB2 não diferencia entre nulos que significam dados desconhecidos e aqueles que significam dados não aplicáveis.
Essa distinção deve ser feita pela lógica do programa de cada aplicativo.
Porém, lembre-se de que usar null para indicar "não aplicável" pode ser uma indicação de design inadequado do banco de dados.
Ao modelar e normalizar adequadamente suas estruturas de dados, você geralmente pode eliminar a necessidade de usar valores nulos para indicar que uma coluna
é inaplicável para uma linha específica.
Por exemplo, considere a seguinte tabela:
CREATE TABLE EMP
(EMPNO INTEGER NOT NULL,
LAST_NAME CHAR(20) NOT NULL,
FIRST_NAME CHAR(15) NOT NULL,
STREET_ADDR CHAR(30) NOT NULL WITH DEFAULT,
CITY CHAR(12) NOT NULL WITH DEFAULT,
STATE CHAR(2) NOT NULL WITH DEFAULT,
POSTAL_CODE CHAR(10) NOT NULL WITH DEFAULT,
EMP_TYPE CHAR(1) NOT NULL
CHECK(EMP_TYPE IN 'F', 'C', 'P'),
HIRE_DATE DATE,
SALARY DECIMAL(9,2),
BILLING_RATE DECIMAL(5,2));
Nesse caso, temos um código na coluna EMP_TYPE que pode conter F (tempo integral), C (contratado) ou P (tempo parcial).
Também temos uma coluna SALARY preenchida para funcionários de período integral e meio período, mas definida como nula para contratados; e uma coluna
BILLING_RATE preenchida por contratados, mas definida como nula para funcionários de período integral e meio período.
Além disso, a coluna HIRE_DATE está definida como nula para os contratados.
Bem, aqui temos três colunas definidas como nulas (ou não) com base em outros valores na tabela.
Podemos projetar nossa solução para esse problema criando uma tabela separada para funcionários e contratados.
Se colunas adicionais fossem necessárias para funcionários de período integral que não aplicassem funcionários de meio período, poderíamos até dividir a tabela
de funcionários em duas: uma para período integral e outra para meio período.
Depois disso, não é mais necessário usar null para dados inaplicáveis.
Variáveis Indicadoras
O DB2 representa nulo em uma coluna "oculta" especial conhecida como variável de indicador.
Uma variável de indicador é definida para o DB2 para cada coluna que pode aceitar nulos.
A variável do indicador é transparente para um usuário final, mas deve ser fornecida ao se programar em um idioma host (como COBOL ou PL / I).
O indicador nulo é usado pelo DB2 para rastrear se sua coluna associada é nula ou não.
Um valor positivo ou um valor 0 significa que a coluna não é nula e qualquer valor real armazenado na coluna é válido.
Se uma coluna CHAR estiver truncada na recuperação porque a variável do host não é grande o suficiente, o valor do indicador conterá o comprimento original
da coluna truncada.
Um valor negativo indica que a coluna está definida como nula.
Se o valor for -2, a coluna foi configurada como nula como resultado de um erro de conversão de dados.
Vamos tirar um momento para esclarecer um mal-entendido comum aqui:
nulos NUNCA economizam espaço de armazenamento no DB2 para OS / 390 ez / OS.
Cada coluna anulável requer um byte adicional de armazenamento para o indicador nulo.
Portanto, uma coluna CHAR (10) anulável exigirá 11 bytes de armazenamento por linha - 10 para os dados e 1 para o indicador nulo.
Este é o caso, independentemente de a coluna estar definida como nula ou não.
O DB2 para Linux, Unix e Windows possui uma opção de compactação que permite que as colunas definidas como nulas economizem espaço.
O uso desta opção faz com que o DB2 elimine o espaço não utilizado de uma linha em que as colunas estão definidas como nulas.
Essa opção não está disponível no mainframe.
Sintaxe
Cada coluna definida em uma tabela do DB2 deve ser designada como permitindo ou não nulos.
Uma coluna é definida como anulável - o que significa que pode ser configurada como NULL - no DDL de criação da tabela.
Nulo é o padrão se nada for especificado após o nome da coluna.
Para proibir que a coluna seja configurada como NULL, você deve especificar explicitamente NOT NULL após o nome da coluna.
Na tabela de exemplo a seguir, COL1 e COL3 podem ser definidos como nulos, mas não COL2, COL4 ou COL5:
CREATE TABLE SAMPLE1
(COL1 INTEGER,
COL2 CHAR(10) NOT NULL,
COL3 CHAR(5),
COL4 DATE NOT NULL WITH DEFAULT,
COL5 TIME NOT NULL);
Nas instruções SELECT, o teste para nulo é realizado de maneira diferente do teste para outros "valores".
Você não pode especificar WHERE COL = NULL, porque isso não faz sentido.
Lembre-se de que null é uma falta de valor, portanto a coluna não é igual a nada. Em vez disso, você teria que codificar WHERE COL IS [NOT] NULL.
Nas instruções INSERT, NULL pode ser especificado na cláusula VALUES para indicar que uma coluna deve ser configurada como NULL; mas nas instruções UPDATE,
você pode usar o predicado de igualdade (=) para atribuir uma coluna a NULL.Ao inserir dados, se o usuário não conseguir fazer uma entrada em uma coluna que permita nulos, o DB2 fornecerá o NULL como padrão (a menos que exista outro
valor padrão).
Se uma tentativa de inserir NULL for feita em uma coluna definida como NOT NULL, a instrução falhará.
Orientação
Agora que você tem um bom entendimento dos conceitos básicos de nulos, vamos revisar algumas diretrizes para seu uso.
Sempre que possível, evite nulos nas colunas que devem participar da lógica aritmética (por exemplo, valores monetários DECIMAIS) e, principalmente, quando as
funções serão usadas.
As funções AVG, COUNT DISTINCT, SUM, MAX e MIN omitem as ocorrências da coluna definidas como nulas. A função COUNT (*), no entanto, não omite colunas definidas
como nulas porque opera em linhas.
Portanto, o AVG não é igual a SUM / COUNT (*) quando a média está sendo calculada para uma coluna que pode conter nulos.
Para esclarecer com um exemplo, se a coluna COMM for anulável, o resultado da seguinte consulta:
SELECT AVG(COMM)
FROM DSN8810.EMP;
não é o mesmo para esta consulta:
SELECT SUM(COMM)/COUNT(*)
FROM DSN8810.EMP;
Portanto, para evitar confusão, evite nulos nas colunas envolvidas nas funções matemáticas sempre que possível.
Quando as colunas DATE, TIME e TIMESTAMP puderem ser desconhecidas, considere criá-las como anuláveis.
O DB2 verifica se apenas datas, horários e carimbos de data / hora válidos são colocados em colunas definidas como tal.
Se a coluna puder ser desconhecida, ela deverá ser definida como anulável porque o padrão para essas colunas é a data atual, a hora atual e o carimbo de
data / hora atual (a menos que explicitamente definido de outra forma usando a cláusula DEFAULT).
Nulo, portanto, é a única opção viável para a gravação de datas, horas e carimbos de data e hora ausentes (a menos que você escolha uma data válida específica
que não seja usada por seus aplicativos para indicar desconhecida).
Para todas as outras colunas, determine se a nulidade pode ser benéfica antes de permitir nulos.
Considere estas regras de operação:
Quando uma coluna anulável participa de uma cláusula ORDER BY ou GROUP BY, os nulos retornados são agrupados na extremidade superior da ordem de classificação.
Os nulos são considerados iguais quando as duplicatas são eliminadas por SELECT DISTINCT ou COUNT (coluna DISTINCT).
Um índice exclusivo considera nulos equivalentes e não permite entradas duplicadas devido à existência de nulos, a menos que a cláusula WHERE NOT NULL seja
especificada no índice.
Para comparação em uma instrução SELECT, duas colunas nulas não são consideradas iguais.
Quando uma coluna anulável participa de um predicado na cláusula WHERE ou HAVING, os nulos encontrados fazem com que a comparação seja avaliada como DESCONHECIDA.
Quando uma coluna anulável participa de um cálculo, o resultado é nulo.
As colunas que participam de uma chave primária não podem ser nulas.
Para testar a existência de nulos, use o predicado especial IS NULL na cláusula WHERE da instrução SELECT.
Você não pode simplesmente declarar WHERE column = NULL. Você deve declarar WHERE a coluna NULL.
É inválido testar se uma coluna é <> NULL ou> = NULL. Tudo isso não faz sentido porque nulo é a ausência de um valor.
Examine essas regras de perto. ORDER BY, GROUP BY, DISTINCT e índices exclusivos consideram nulos iguais e os manipulam adequadamente.
A instrução SELECT, no entanto, considera que a comparação de colunas nulas não é equivalência, mas desconhecida.
Esse tratamento inconsistente de nulos é uma anomalia que você deve lembrar ao usar nulos.
A seguir, são apresentadas várias consultas SQL de amostra e o efeito nulo tem sobre elas.
SELECT JOB, SUM(SALARY)
FROM DSN8810.EMP
GROUP BY JOB;
Esta consulta retorna o salário médio para cada tipo de trabalho.
Todas as instâncias em que JOB é nulo serão agrupadas na parte inferior da saída.
SELECT EMPNO
, PROJNO
, ACTNO
, EMPTIME
, EMSTDATE
, EMENDATE
FROM DSN8810.EMPPROJACT
WHERE EMSTDATE = EMENDATE;
Esta consulta recupera todas as ocorrências nas quais a data de início do projeto é igual à data de término do projeto.
Essas informações são claramente errôneas, como qualquer pessoa que já trabalhou em um projeto de desenvolvimento de software pode atestar.
A consulta não retorna nenhuma linha em que datas ou ambas as datas sejam nulas por dois motivos: (1) duas colunas nulas nunca são iguais para fins de
comparação e (2) quando uma das colunas de um operador de comparação é nula, o resultado É desconhecido.
UPDATE DSN8810.DEPT
SET MGRNO = NULL
WHERE MGRNO = '000010';
Esta consulta define a coluna MGRNO como nula, sempre que MGRNO atualmente seja igual a '000010' na tabela DEPT.;>
Ao criar tabelas, trate as colunas anuláveis ??da mesma forma que faria com qualquer outra coluna.
Alguns DBAs aconselham você a colocar colunas anuláveis ??do mesmo tipo de dados após colunas não anuláveis.
Isso deve ajudar na administração das colunas nulas, mas na verdade não ajuda - e pode doer.
A sequência de colunas anuláveis ??dessa maneira não fornece benefícios claros e deve ser evitada.
© Copyright Craig Mullins.