Estou usando o MySQL 5.7 e percebi algo que não consigo explicar para mim mesmo com meu conhecimento atual, então aqui vai.
Uma data "inválida" é 0000-00-00
considerada igual NULL
a um date
tipo de coluna sem possibilidades de valores anuláveis? Veja o exemplo a seguir:
create table if not exists example
(
id int auto_increment primary key,
doskip date default '0000-00-00' not null
);
INSERT INTO example VALUES(1, '0000-00-00'), (2, '0000-00-00'), (3, '0000-00-00');
Ter o que foi dito acima e executar as seguintes consultas me deu exatamente a mesma contagem: 3 e eu me pergunto por que, há alguma explicação para isso?
SELECT COUNT(*) FROM example j WHERE j.doskip = '0000-00-00';
SELECT COUNT(*) FROM example j WHERE j.doskip IS NULL;
Aqui está um Fiddle mostrando esse comportamento, é por causa do modo?
'0000-00-00' é um marcador mágico que é "nulo" e "não nulo" simultaneamente. Você pode estender seu violino com:
ou mesmo:
Este último é uma contradição, mas todas as linhas são qualificadas. Você pode trazer alguma sanidade às versões mais antigas do MySQL configurando sql_mode como
NO_ZERO_DATE
. Enquanto você está nisso, adicione tambémONLY_FULL_GROUP_BY
Outra indicação de que não se comporta como null é que
avalia como TRUE, enquanto:
avalia como FALSO. Você pode tentar com:
O MySQL 8 melhorou muito em comparação com as versões anteriores. Você pode considerar atualizar se quiser evitar esse tipo de peculiaridade
Pelo que entendi,
0000-00-00
em umadate
coluna de tipo de dados é considerado um arquivoNULL
.De problemas ao usar colunas DATE
Na declaração acima não é mencionado especificamente que 0000-00-00 é tratado como NULL , mas acho que em algum lugar do código isso é necessário.
Outra declaração dos documentos
Observe que isso se aplica a
date
umdatetime
tipo de dados, nãotimestamp
Minha sugestão
Corrija o design da tabela tornando o padrão de data doskip nulo, já que o padrão de data doskip '0000-00-00' não é nulo, não faz nenhum sentido de qualquer maneira. Habilite NO_ZERO_DATE com modo estrito, substitua todos os valores de '0000-00-00' por NULL.
Nulo é considerado um valor desconhecido e só pode ser avaliado usando is null/is not null. '0000-00-00' é considerada uma data desconhecida e é por isso que os desenvolvedores podem ter aplicado as mesmas regras.