web-dev-qa-db-fra.com

Comment définir une valeur par défaut pour une colonne MySQL Datetime?

Comment définir une valeur par défaut pour une colonne MySQL Datetime?

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

831
Brian Boatright

IMPORTANT EDIT: Il est maintenant possible d'y parvenir avec les champs DATETIME depuis MySQL 5.6.5 , jetez un oeil à la autre post 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 ou cette valeur sera automatiquement réinitialisée sur "now ()" lors de la mise à jour. Cela signifie que si vous ne souhaitez 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" maintenant () ". Bizarre, mais vrai. J'espère que ça aide. J'utilise 5.5.56-MariaDB **

812
sebthebert

Dans la version 5.6.5, il est possible de définir une valeur par défaut sur une colonne datetime et même de créer une colonne qui sera mise à jour lors de la mise à jour de la ligne. 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

553
Gustav Bertram

MySQL ( avant la version 5.6.5 ) n'autorisait pas l'utilisation de fonctions pour les valeurs DateTime par défaut. TIMESTAMP ne convient pas à cause de son comportement étrange et son utilisation en tant que donnée d'entrée n'est pas recommandée. (Voir Valeurs par défaut du type 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 déclencheur sur cette table "Before Insert" et "SET NEW.DateCreated=NOW()" et cela fonctionne très bien.

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

141
Stephan Unrau

Pour moi, l’approche de déclenchement a fonctionné le mieux, mais j’ai trouvé un problème avec l’approche. Considérez le déclencheur de base pour définir un champ de date sur 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 bien, mais disons que vous voulez définir le champ manuellement via une instruction INSERT, comme ceci:

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

En réalité, le déclencheur écrase immédiatement la valeur fournie pour le champ. Le seul moyen de définir une heure non actuelle est donc une instruction UPDATE suivante: 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 cela prendra, sinon, le temps par défaut sera affiché. C'est toujours ghetto par rapport à quelque chose de propre comme DEFAULT GETDATE () dans la définition de la table, mais nous nous rapprochons!

129
John Larson

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

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 vous le souhaiteriez avec la fonction now (). L'insertion de valeurs NULL 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 change le updated_dt. Si vous insérez des enregistrements via le navigateur de requêtes MySQL, vous avez besoin d'une étape supplémentaire, d'un déclencheur pour gérer le 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] _ [nom_table] _ [insérer]

26
user188217

Vous pouvez utiliser des déclencheurs pour faire ce type de choses.

CREATE TABLE `MyTable` (
`MyTable_ID`  int UNSIGNED NOT NULL AUTO_INCREMENT ,
`MyData`  varchar(10) NOT NULL ,
`CreationDate`  datetime NULL ,
`UpdateDate`  datetime NULL ,
PRIMARY KEY (`MyTable_ID`)
)
;

CREATE TRIGGER `MyTable_INSERT` BEFORE INSERT ON `MyTable`
FOR EACH ROW BEGIN
        -- Set the creation date
    SET new.CreationDate = now();

        -- Set the udpate date
    Set new.UpdateDate = now();
END;

CREATE TRIGGER `MyTable_UPDATE` BEFORE UPDATE ON `MyTable`
FOR EACH ROW BEGIN
        -- Set the udpate date
    Set new.UpdateDate = now();
END;
22
Donald

Pour tous ceux qui ont perdu courage à essayer de définir une valeur par défaut DATETIME dans MySQL, je sais exactement ce que vous ressentez. Donc voici est:

ALTER TABLE  `table_name` CHANGE `column_name` DATETIME NOT NULL DEFAULT 0

Observez attentivement que je n’ai pas ajouté de guillemets simples/doubles autour de

Je saute littéralement après avoir résolu celui-ci: D

16
Augiwan

MySQL 5.6 a corrigé ce problème .

ALTER TABLE mytable CHANGE mydate datetime NOT NULL DEFAULT 'CURRENT_TIMESTAMP'
13
Steven Lloyd

c'est vraiment une terrible nouvelle. Voici une demande de bogue/fonctionnalité attendue depuis longtemps . cette discussion parle aussi des limites du type de données timestamp.

Je me demande sérieusement quel est le problème avec la mise en œuvre de cette chose.

12
Kinjal Dixit

Si vous avez déjà créé la table, vous pouvez utiliser

Pour changer la valeur par défaut à la date actuelle

ALTER TABLE <TABLE_NAME> 
CHANGE COLUMN <COLUMN_NAME> <COLUMN_NAME> DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP;

Pour changer la valeur par défaut en '2015-05-11 13:01:01'

ALTER TABLE <TABLE_NAME> 
CHANGE COLUMN <COLUMN_NAME> <COLUMN_NAME> DATETIME NOT NULL DEFAULT '2015-05-11 13:01:01';
10

J'utilise MySql Server 5.7.11 et cette phrase:

ALTER TABLE table_name CHANGE date_column datetime NOT NULL DEFAULT '0000-00-00 00:00:00'

ne fonctionne pas . Mais ce qui suit:

ALTER TABLE table_name CHANGE date_column datetime NOT NULL DEFAULT '1000-01-01 00:00:00'

ne fonctionne que .

En tant que sidenote , il est mentionné dans le mysql docs :

Le type DATE est utilisé pour les valeurs avec une partie date mais pas une partie heure. MySQL récupère et affiche les valeurs DATE au format 'AAAA-MM-JJ'. La plage prise en charge est "1000-01-01" à "9999-12-31".

même s'ils disent aussi:

Les valeurs DATE, DATETIME ou TIMESTAMP non valides sont converties en la valeur "zéro" du type approprié ("0000-00-00" ou "0000-00-00 00:00:00").

8
Evhz

Lorsque vous définissez des déclencheurs multilignes, vous devez modifier le délimiteur, car le point-virgule sera considéré par le compilateur MySQL comme une fin de déclencheur et génère une erreur. par exemple.

DELIMITER //
CREATE TRIGGER `MyTable_UPDATE` BEFORE UPDATE ON `MyTable`
FOR EACH ROW BEGIN
        -- Set the udpate date
    Set new.UpdateDate = now();
END//
DELIMITER ;
7
Drawin Kumar

Pour tous ceux qui utilisent la colonne TIMESTAMP comme solution, je souhaite appuyer la limitation suivante du manuel:

http://dev.mysql.com/doc/refman/5.0/en/datetime.html

"Le type de données TIMESTAMP a une plage allant de '1970-01-01 00:00:01' à ' 2038-01-19 03:14:07 'UTC. Ses propriétés varient en fonction de la version de MySQL et du mode SQL dans lequel le serveur est exécuté. Ces propriétés sont décrites plus loin dans cette section. "

Donc, cela va évidemment casser votre logiciel dans environ 28 ans.

Je crois que la seule solution du côté de la base de données consiste à utiliser des déclencheurs comme indiqué dans d'autres réponses.

7
Fabian

Vous pouvez utiliser now () pour définir la valeur d'une colonne datetime, mais gardez à l'esprit que vous ne pouvez pas l'utiliser comme valeur par défaut.

6
KernelM

Bien que vous ne puissiez pas faire cela avec DATETIME dans la définition par défaut, vous pouvez simplement incorporer une instruction select dans votre instruction insert comme ceci:

INSERT INTO Yourtable (Field1, YourDateField) VALUES('val1', (select now()))

Notez le manque de guillemets autour de la table.

Pour MySQL 5.5

5
George

Voici comment le faire sur MySQL 5.1:

ALTER TABLE `table_name` CHANGE `column_name` `column_name` 
TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;

Je ne sais pas pourquoi vous devez entrer le nom de la colonne deux fois.

4
Samuel

Si vous essayez de définir NOW comme valeur par défaut, je ne pense pas que MySQL le prenne en charge. Dans MySQL, vous ne pouvez pas utiliser une fonction ou une expression comme valeur par défaut pour tout type de colonne, à l'exception de la colonne de type de données TIMESTAMP, pour laquelle vous pouvez spécifier CURRENT_TIMESTAMP comme valeur par défaut.

3
Vijesh VP

Utilisez le code suivant

DELIMITER $$

    CREATE TRIGGER bu_table1_each BEFORE UPDATE ON table1 FOR EACH ROW
    BEGIN
      SET new.datefield = NOW();
    END $$

    DELIMITER ;
2
Rana Aalamgeer
CREATE TABLE `testtable` (
    `id` INT(10) NULL DEFAULT NULL,
    `colname` DATETIME NULL DEFAULT '1999-12-12 12:12:12'
)

Dans la requête ci-dessus pour créer 'testtable', j'ai utilisé '1999-12-12 12:12:12' comme valeur par défaut pour la colonne DATETIME colname

2
Fathah Rehman P

Je pense que c'est simple dans mysql puisque mysql la fonction intégrée appelée now () qui donne l'heure actuelle (heure de l'insertion).

Donc, votre requête devrait ressembler à celle-ci

CREATE TABLE defaultforTime(
    `creation_time`     DATETIME DEFAULT CURRENT_TIMESTAMP,
    `modification_time` DATETIME default now()
);

Je vous remercie.

1
Deepak N

Si vous essayez de définir NOW () comme valeur par défaut, MySQL vous recommande de modifier le type de cette colonne TIMESTAMP au lieu de DATETIME. TIMESTAMP a la date et l'heure actuelles par défaut..je pense que cela résoudra votre problème ..

0
Dhrumil Shah

Prenez par exemple si j'avais une table nommée 'site' avec une colonne created_at et une colonne update_at qui étaient à la fois DATETIME et ont besoin de la valeur par défaut de maintenant, je pourrais exécuter le code SQL suivant pour y parvenir.

 ALTER TABLE `site` CHANGE` created_at` 'created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP; 
 
 ALTER TABLE `site` CHANGE` created_at` `created_at` DATETIME NULL DEFAULT NULL; 
 
 ALTER TABLE `site` CHANGE` jour_at` `jour_at` TIMESTAMP PAS NULL DEFAUT CURRENT_TIMESTAMP; 
 
 ALTER TABLE` site` CHANGEMENT `jour_at`` jour_at` DATETIME NULL DEFAULT NULL; 

La séquence d'instructions est importante car une table ne peut pas avoir deux colonnes de type TIMESTAMP avec les valeurs par défaut de CUREENT TIMESTAMP

0
Joseph Persie

Voici mon exemple de déclencheur:

/************ ROLE ************/
drop table if exists `role`;
create table `role` (
    `id_role` bigint(20) unsigned not null auto_increment,
    `date_created` datetime,
    `date_deleted` datetime,
    `name` varchar(35) not null,
    `description` text,
    primary key (`id_role`)
) comment='';

drop trigger if exists `role_date_created`;
create trigger `role_date_created` before insert
    on `role`
    for each row 
    set new.`date_created` = now();
0
Lucas Moyano Angelini