1046 votes

Comment définir une valeur par défaut pour une colonne MySQL de type datetime ?

Comment définir une valeur par défaut pour une colonne MySQL de type datetime ?

Dans SQL Server, c'est getdate() . Quel est l'équivalent pour MySQL ? J'utilise MySQL 5.x, si c'est un facteur.

7 votes

J'utilise CURRENT_TIMESTAMP dans ma table mysql (pas dans la requête), peut-être que cela peut être utile aussi.

19 votes

Cette fonctionnalité a maintenant été ajoutée à MySQL 5.6.5. J'espère que cela aidera quelqu'un. optimize-this.blogspot.co.uk/2012/04/

0 votes

@GhostInTheSecureShell toute une mission pour l'installer, au moins sur Debian, mais définitivement une fonctionnalité géniale. Je pense qu'un jour toutes ces questions "deux CURRENT_TIMESTAMP" seront résolues !

998voto

sebthebert Points 4038

MODIFICATION IMPORTANTE : Il est désormais possible d'y parvenir avec des champs de type DATETIME puisque MySQL 5.6.5 Jetez un coup d'œil à la autre poste ci-dessous...

Les versions précédentes ne peuvent pas faire cela avec DATETIME...

Mais vous pouvez le faire avec TIMESTAMP :

mysql> create table test (str varchar(32), ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP);
Query OK, 0 rows affected (0.00 sec)

mysql> desc test;
+-------+-------------+------+-----+-------------------+-------+
| Field | Type        | Null | Key | Default           | Extra |
+-------+-------------+------+-----+-------------------+-------+
| str   | varchar(32) | YES  |     | NULL              |       | 
| ts    | timestamp   | NO   |     | CURRENT_TIMESTAMP |       | 
+-------+-------------+------+-----+-------------------+-------+
2 rows in set (0.00 sec)

mysql> insert into test (str) values ("demo");
Query OK, 1 row affected (0.00 sec)

mysql> select * from test;
+------+---------------------+
| str  | ts                  |
+------+---------------------+
| demo | 2008-10-03 22:59:52 | 
+------+---------------------+
1 row in set (0.00 sec)

mysql>

CAVEAT : Si vous définissez une colonne avec CURRENT_TIMESTAMP ON par défaut, vous devrez TOUJOURS spécifier une valeur pour cette colonne, sinon la valeur se réinitialisera automatiquement à "now()" lors de la mise à jour. Cela signifie que si vous ne voulez pas que la valeur change, votre instruction UPDATE doit contenir "[votre nom de colonne] = [votre nom de colonne]" (ou une autre valeur) ou la valeur deviendra "now()". Bizarre, mais vrai. J'utilise la version 5.5.56-MariaDB.

437 votes

Il est important de noter que datetime a une plage de 1000-9999, mais la gamme pour le timestamp est seulement 1970-2038 . cela peut poser un problème si votre système doit stocker des dates de naissance, ou si vous devez gérer quelque chose comme le plan de paiement d'un prêt hypothécaire sur 30 ans. dev.mysql.com/doc/refman/5.0/fr/datetime.html

19 votes

Faites également attention à l'horodatage car il se met à jour automatiquement comme par magie ... voir la réponse suivante stackoverflow.com/a/1483959/233906

7 votes

Es est possible à partir de la version 5.6.5, voir la réponse de Gustav ci-dessous (je me rends compte que votre réponse a été postée lorsque MySQL était encore 5.0 !)

708voto

Gustav Bertram Points 4555

Dans la version 5.6.5, il est possible de définir une valeur par défaut sur une colonne de date, et même de créer une colonne qui se met à jour lorsque la ligne est mise à jour. La définition du type :

CREATE TABLE foo (
    `creation_time`     DATETIME DEFAULT CURRENT_TIMESTAMP,
    `modification_time` DATETIME ON UPDATE CURRENT_TIMESTAMP
)

Référence : http://optimize-this.blogspot.com/2012/04/datetime-default-now-finally-available.html

5 votes

Valeur par défaut non valide pour 'menu_creation_time'.

2 votes

@FernandoTrindade Vous avez besoin de MySQL version 5.6.5 ou ultérieure. Vous pouvez le voir fonctionner ici : sqlfiddle.com/#!9/dd2be

1 votes

@GustavBertram, j'utilise la version 5.6.22, mais j'ai toujours l'erreur suivante : CREATE TABLE tbl ( InsertDate DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, UpdateDate TIMESTAMP NULL ON UPDATE CURRENT_TIMESTAMP(6) ) ; Code d'erreur : 1294. Clause ON UPDATE invalide pour la colonne 'UpdateDate'.

158voto

Stephan Unrau Points 989

MySQL ( avant la version 5.6.5 ) ne permet pas d'utiliser des fonctions pour les valeurs de date et d'heure par défaut. TIMESTAMP ne convient pas en raison de son comportement étrange et il n'est pas recommandé de l'utiliser comme donnée d'entrée. (Voir Valeurs par défaut des types de données MySQL .)

Cela dit, vous pouvez accomplir ceci en créant un déclencheur .

J'ai une table avec un champ DateCreated de type DateTime. J'ai créé un trigger sur cette table "Before Insert" et " SET NEW.DateCreated=NOW() "et cela fonctionne très bien.

J'espère que cela aidera quelqu'un.

22 votes

CREATE TRIGGER trigger_foo_SetCreatedAt BEFORE INSERT ON foo FOR EACH ROW SET NEW.created_at = UTC_TIMESTAMP() ;

6 votes

Il est probablement préférable d'utiliser un horodatage plutôt qu'un déclencheur pour des raisons de sécurité (maintenance). C'est un cas d'utilisation trop trivial pour un trigger, bien que ce soit une solution.

8 votes

Vous voudrez probablement définir la valeur par défaut uniquement IF NEW.created_at IS NOT NULL

135voto

John Larson Points 799

Pour moi, c'est l'approche du déclenchement qui a le mieux fonctionné, mais j'ai trouvé un problème avec cette approche. Prenons le déclencheur de base pour définir un champ de date à l'heure actuelle lors de l'insertion :

CREATE TRIGGER myTable_OnInsert BEFORE INSERT ON `tblMyTable`
    FOR EACH ROW SET NEW.dateAdded = NOW();

C'est généralement très bien, mais disons que vous voulez définir le champ manuellement via l'instruction INSERT, comme ceci :

INSERT INTO tblMyTable(name, dateAdded) VALUES('Alice', '2010-01-03 04:30:43');

Ce qui se passe, c'est que le déclencheur écrase immédiatement la valeur que vous avez fournie pour le champ, et donc la seule façon de définir une heure non courante est une déclaration UPDATE de suivi - beurk ! Pour remplacer ce comportement lorsqu'une valeur est fournie, essayez ce déclencheur légèrement modifié avec l'opérateur IFNULL :

CREATE TRIGGER myTable_OnInsert BEFORE INSERT ON `tblMyTable`
    FOR EACH ROW SET NEW.dateAdded = IFNULL(NEW.dateAdded, NOW());

Cela donne le meilleur des deux mondes : vous pouvez fournir une valeur pour votre colonne de date et elle sera prise, et sinon elle sera par défaut à l'heure actuelle. C'est encore un peu léger par rapport à quelque chose de propre comme DEFAULT GETDATE() dans la définition de la table, mais on s'en rapproche !

6 votes

+1 pour avoir reconnu le problème de l'écrasement des valeurs utilisateur explicites lors de l'insertion.

2 votes

Je pense personnellement que c'est la meilleure façon de procéder. TIMESTAMP a en effet un comportement étrange et je n'écrirais jamais un code qui a une limitation à 2038 ans.

0 votes

Peu importe, j'ai trouvé. J'ai oublié de définir le champ pour autoriser NULL . Plus d'avertissements.

43voto

J'ai pu résoudre ce problème en utilisant cette instruction alter sur ma table qui avait deux champs de date.

ALTER TABLE `test_table`
  CHANGE COLUMN `created_dt` `created_dt` TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00',
  CHANGE COLUMN `updated_dt` `updated_dt` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;

Cela fonctionne comme on peut s'attendre à ce que la fonction now() fonctionne. L'insertion de valeurs nulles ou l'ignorance des champs created_dt et updated_dt donne une valeur d'horodatage parfaite dans les deux champs. Toute mise à jour de la ligne modifie le champ updated_dt. Si vous insérez des enregistrements via le navigateur de requêtes MySQL, vous avez besoin d'une étape supplémentaire, un déclencheur pour traiter le champ created_dt avec un nouvel horodatage.

CREATE TRIGGER trig_test_table_insert BEFORE INSERT ON `test_table`
    FOR EACH ROW SET NEW.created_dt = NOW();

Le déclencheur peut être ce que vous voulez, j'aime juste la convention de nommage [trig]_[mon_nom_de_table]_[insert].

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X