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?
À 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.
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)
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.
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
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);
Mais voici la belle partie:
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)
)
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/
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
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'
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 )
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/