web-dev-qa-db-fra.com

Avoir une colonne timestamp Créée et Dernière mise à jour dans MySQL 4.0

J'ai le schéma de table suivant;

CREATE TABLE `db1`.`sms_queue` (
  `Id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
  `Message` VARCHAR(160) NOT NULL DEFAULT 'Unknown Message Error',
  `CurrentState` VARCHAR(10) NOT NULL DEFAULT 'None',
  `Phone` VARCHAR(14) DEFAULT NULL,
  `Created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `LastUpdated` TIMESTAMP NOT NULL ON UPDATE CURRENT_TIMESTAMP,
  `TriesLeft` tinyint NOT NULL DEFAULT 3,
  PRIMARY KEY (`Id`)
)
ENGINE = InnoDB;

Il échoue avec l'erreur suivante:

ERROR 1293 (HY000): Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause.

Ma question est la suivante: puis-je avoir ces deux champs? ou dois-je définir manuellement un champ LastUpdated lors de chaque transaction?

119
Xenph Yan

À partir de la documentation MySQL 5.5 :

L'horodatage actuel d'une colonne d'une table dans une table peut être la valeur par défaut pour l'initialisation de la colonne, la valeur de mise à jour automatique ou les deux. Il n'est pas possible que l'horodatage actuel soit la valeur par défaut pour une colonne et la valeur de mise à jour automatique pour une autre colonne.

Modifications dans MySQL 5.6.5 :

Auparavant, au plus une colonne TIMESTAMP par table pouvait être automatiquement initialisée ou mise à jour à la date et à l'heure actuelles. Cette restriction a été levée. Toute définition de colonne TIMESTAMP peut avoir toute combinaison de clauses DEFAULT CURRENT_TIMESTAMP et ON UPDATE CURRENT_TIMESTAMP. De plus, ces clauses peuvent maintenant être utilisées avec les définitions de colonne DATETIME. Pour plus d'informations, voir Initialisation et mise à jour automatiques pour TIMESTAMP et DATETIME.

110
Robert Gamble

Il y a un truc pour avoir les deux horodatages, mais avec un peu de limitation.

Vous ne pouvez utiliser qu'une seule des définitions d'une seule table. Créez les deux colonnes d'horodatage comme ceci: 

create table test_table( 
  id integer not null auto_increment primary key, 
  stamp_created timestamp default '0000-00-00 00:00:00', 
  stamp_updated timestamp default now() on update now() 
); 

Notez qu'il est nécessaire de saisir null dans les deux colonnes pendant insert:

mysql> insert into test_table(stamp_created, stamp_updated) values(null, null); 
Query OK, 1 row affected (0.06 sec)

mysql> select * from test_table; 
+----+---------------------+---------------------+ 
| id | stamp_created       | stamp_updated       |
+----+---------------------+---------------------+
|  2 | 2009-04-30 09:44:35 | 2009-04-30 09:44:35 |
+----+---------------------+---------------------+
2 rows in set (0.00 sec)  

mysql> update test_table set id = 3 where id = 2; 
Query OK, 1 row affected (0.05 sec) Rows matched: 1  Changed: 1  Warnings: 0  

mysql> select * from test_table;
+----+---------------------+---------------------+
| id | stamp_created       | stamp_updated       | 
+----+---------------------+---------------------+ 
|  3 | 2009-04-30 09:44:35 | 2009-04-30 09:46:59 | 
+----+---------------------+---------------------+ 
2 rows in set (0.00 sec)  
82
Bogdan Gusiev

Vous pouvez les avoir tous les deux, enlevez simplement l'indicateur "CURRENT_TIMESTAMP" sur le champ créé. Chaque fois que vous créez un nouvel enregistrement dans la table, utilisez simplement "NOW ()" pour une valeur.

Ou.

Au contraire, supprimez l'indicateur 'ON UPDATE CURRENT_TIMESTAMP' et envoyez le NOW () pour ce champ. De cette façon, cela a plus de sens.

26
Stephen Walcher

Si vous décidez de laisser MySQL gérer la mise à jour des horodatages, vous pouvez configurer un déclencheur pour mettre à jour le champ à l'insertion.

CREATE TRIGGER <trigger_name> BEFORE INSERT ON <table_name> FOR EACH ROW SET NEW.<timestamp_field> = CURRENT_TIMESTAMP;

Référence MySQL: http://dev.mysql.com/doc/refman/5.0/fr/triggers.html

24
webkraller

Voici comment vous pouvez avoir des champs createDate/lastModified automatiques et flexibles à l'aide de déclencheurs:

Commencez par les définir comme ceci:

CREATE TABLE `entity` (
  `entityid` int(11) NOT NULL AUTO_INCREMENT,
  `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `lastModified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `name` varchar(255) DEFAULT NULL,
  `comment` text,
  PRIMARY KEY (`entityid`),
)

Ajoutez ensuite ces déclencheurs:

DELIMITER ;;
CREATE trigger entityinsert BEFORE INSERT ON entity FOR EACH ROW BEGIN SET NEW.createDate=IF(ISNULL(NEW.createDate) OR NEW.createDate='0000-00-00 00:00:00', CURRENT_TIMESTAMP, IF(NEW.createDate<CURRENT_TIMESTAMP, NEW.createDate, CURRENT_TIMESTAMP));SET NEW.lastModified=NEW.createDate; END;;
DELIMITER ;
CREATE trigger entityupdate BEFORE UPDATE ON entity FOR EACH ROW SET NEW.lastModified=IF(NEW.lastModified<OLD.lastModified, OLD.lastModified, CURRENT_TIMESTAMP);
  • Si vous insérez sans spécifier createDate ou lastModified, ils seront égaux et définis sur l'horodatage actuel.
  • Si vous les mettez à jour sans spécifier createDate ou lastModified, lastModified sera défini sur l'horodatage actuel.

Mais voici la belle partie:

  • Si vous insérez, vous pouvez spécifier un createDate plus ancien que l'horodatage actuel, permettant ainsi aux importations des périodes plus anciennes de fonctionner correctement (lastModified sera égal à createDate).
  • Si vous (update} _, vous pouvez spécifier un lastModified plus ancien que la valeur précédente ('0000-00-00 00:00:00' fonctionne bien), permettant de mettre à jour une entrée si vous êtes faire des changements esthétiques (corriger une faute de frappe dans un commentaire) et que vous voulez conserver l'ancien lastModified date. Cela ne modifiera pas la date de la dernière modification.
23
alien

Depuis MySQL 5.6, c'est facile à essayer ... essayez-le: 

create table Tweet ( 
    id integer not null auto_increment primary key, 
    stamp_created timestamp default now(), 
    stamp_updated timestamp default now() on update now(),
    message varchar(163)
)
19
Shaheen Ghiassy
create table test_table( 
id integer not null auto_increment primary key, 
stamp_created timestamp default '0000-00-00 00:00:00', 
stamp_updated timestamp default now() on update now() 
); 

source: http://gusiev.com/2009/04/update-and-create-timestamps-with-mysql/

4
user5903005

Ce problème semblait avoir été résolu dans MySQL 5.6. Je l’ai remarqué jusqu’à MySQL 5.5; voici un exemple de code:

DROP TABLE IF EXISTS `provider_org_group` ;
CREATE TABLE IF NOT EXISTS `provider_org_group` (
  `id` INT NOT NULL,
  `name` VARCHAR(100) NOT NULL,
  `type` VARCHAR(100) NULL,
  `inserted` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `insert_src_ver_id` INT NULL,
  `updated` TIMESTAMP NULL ON UPDATE CURRENT_TIMESTAMP,
  `update_src_ver_id` INT NULL,
  `version` INT NULL,
  PRIMARY KEY (`id`),
  UNIQUE INDEX `id_UNIQUE` (`id` ASC),
  UNIQUE INDEX `name_UNIQUE` (`name` ASC))
ENGINE = InnoDB;

Exécuter ceci sur MySQL 5.5 donne:

ERROR 1293 (HY000): Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause

En cours d'exécution sur MySQL 5.6 

0 row(s) affected   0.093 sec
4
Kingz

je pense que c'est la meilleure requête pour stamp_created et stamp_updated

CREATE TABLE test_table( 
    id integer not null auto_increment primary key, 
    stamp_created TIMESTAMP DEFAULT now(), 
    stamp_updated TIMESTAMP DEFAULT '0000-00-00 00:00:00' ON UPDATE now() 
); 

car lorsque l'enregistrement est créé, stamp_created doit être rempli par now() et stamp_updated doit être rempli par '0000-00-00 00:00:00'

2
anonymouse

Pour MySQL 5.7.21, j’utilise les logiciels suivants et fonctionne très bien:

CREATE TABLE Posts ( modified_at horodatage NOT NULL DEFAUT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, created_at horodatage NON NULL DEFAUT CURRENT_TIMESTAMP ) 

0
Ioannis Chrysochos

Mon hébergeur est bloqué sur la version 5.1 de mysql, donc toute personne comme moi qui n'a pas l'option de mise à niveau peut suivre les instructions suivantes: 

http://joegornick.com/2009/12/30/mysql-created-and-modified-date-fields/

0
Nathan Prather