web-dev-qa-db-fra.com

Insertion de NULL dans l'horodatage MySQL

J'observe un comportement inattendu lors de l'insertion/la mise à jour de NULL dans une colonne d'horodatage MySQL.

Considérez les affirmations suivantes.

create table temp(id int, hireDate timestamp default 0);
insert into temp (id) values(1);
insert into temp (id, hireDate) values(2, null);
select * from temp;
id  hireDate
-----------------------------
1   
2   2012-09-19 10:54:10.0

La première insertion (lorsque hiredate n'est pas spécifié dans le code SQL, hireDate est null(0), ce qui est attendu.

Cependant, lorsqu'un null explicite est passé en SQL, la date actuelle est insérée, ce qui est inattendu. Pourquoi cela arrive-t-il?

Remarque: Hibernate utilise un deuxième type d’insert et pose donc un problème. Comment insérer null dans une colonne d'horodatage?

33
Rejeev Divakaran

http://dev.mysql.com/doc/refman/5.0/en/timestamp-initialization.html

En outre, vous pouvez initialiser ou mettre à jour une colonne TIMESTAMP à la date et à l'heure actuelles en lui attribuant une valeur NULL, sauf si elle a été définie avec l'attribut NULL pour autoriser les valeurs NULL. 

31
Juris Malinens

Vous pouvez insérer et mettre à jour NULL dans un horodatage MySQL.

Créer la table:

create table penguins(id int primary key auto_increment, the_time timestamp NULL);

Insérer quelques lignes:

insert into penguins(the_time) values (now());
insert into penguins(the_time) values (null);
insert into penguins(the_time) values (0);
insert into penguins(the_time) values ('1999-10-10 01:02:03');

Quels tirages:

select * from penguins

1   2015-01-23 15:40:36
2   
3   0000-00-00 00:00:00
4   1999-10-10 01:02:03

La colonne appelée the_time avec le type de données: timestamp dans la deuxième ligne a la valeur NULL.

11
Eric Leschinski

Vous devez modifier la valeur par défaut de la colonne hireDate. La valeur par défaut doit être null

Ce 

create table temp(id int, hireDate timestamp default 0);

Devrait être ceci:

create table temp(id int, hireDate timestamp null);
4
Balkrishan Nagpal

Ne stockez jamais de valeur d'application dans une colonne de type timestamp MySQL . Utilisez le type timestamp uniquement pour l'horodatage dynamique côté serveur de base de données (voir Attributs de colonne DEFAULT et ON UPDATE) . appelant les colonnes 'mysql_row_created_at' et 'mysql_row_updated_at'.

Sachez que MySQL stocke physiquement son type d'horodatage sous la forme d'un UNIX-Epoch-delta numérique, de sorte qu'il dispose d'un fuseau horaire UTC implicite, ce qui le rend insensible aux changements de fuseau horaire au niveau de la session (connexion AKA).

Éloignez-vous du type 'datetime', et plus encore lorsque vous stockez une valeur ayant un fuseau horaire connu. Le type 'datetime' ressemble beaucoup à une chaîne de nombres condensés. Il n'y a pas de détails de fuseau horaire stockés avec cela.

Le type 'date' est généralement bon à utiliser. Sachez cependant que dans certains contextes, il sera interprété comme une date/heure à minuit (du fuseau horaire actif), ce qui entraînera toutes les confusions liées à la "date/heure" que vous devriez éviter.

Pour toute valeur date-heure côté application, utilisez un 'int unsigned', un 'bigint' (signé), un 'double' (signé) ou un décimal (N, P), pour simplement stocker UNIX-Epoch-deltas . Assurez-vous d'afficher la résolution dans un suffixe de nom de colonne, s'il ne s'agit pas de secondes.

Exemples:

`mysql_row_created_at` TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP,
`mysql_row_updated_at` TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,

`Epoch` int unsigned NOT NULL,
`Epoch_ms` bigint NOT NULL,
`Epoch_us` bigint NOT NULL,
`Epoch` double NOT NULL,
`Epoch6` decimal(16,6),

Traitez votre base de données autant que le stockage idiot que possible. Par conséquent, effectuez uniquement des conversions côté application, jamais côté base de données.

Bon à savoir sur:

SELECT @@GLOBAL.TIME_ZONE
, @@SESSION.TIME_ZONE
, @@SESSION.TIMESTAMP
, UNIX_TIMESTAMP(NOW(6))
;
0
druud62