Tener columnas de fecha y hora creadas y actualizadas por última vez en MySQL 4.0
mysql-error-1293 (10)
Tengo el siguiente esquema de tabla;
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;
Falla con el siguiente error:
ERROR 1293 (HY000): Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause.
Mi pregunta es, ¿puedo tener ambos campos? o tengo que configurar manualmente un campo LastUpdated durante cada transacción?
A partir de MySQL 5.6 es fácil ... pruébalo:
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)
)
Así es como puedes tener campos createDate / lastModified automáticos y flexibles usando triggers:
Primero defínalos así:
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`),
)
A continuación, agregue estos factores desencadenantes:
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 inserta sin especificar createDate o lastModified, serán iguales y se establecerán en la marca de tiempo actual.
- Si los actualiza sin especificar createDate o lastModified, lastModified se establecerá en la marca de tiempo actual.
Pero esta es la parte buena:
- Si inserta , puede especificar un createDate anterior a la marca de tiempo actual , lo que permite que las importaciones de tiempos anteriores funcionen bien (lastModified será igual a createDate).
- Si actualiza , puede especificar un lastModified anterior al valor anterior (''0000-00-00 00:00:00'' funciona bien), lo que le permite actualizar una entrada si está haciendo cambios estéticos (corregir un error tipográfico en un comentario ) y desea mantener la fecha anterior lastModified . Esto no modificará la última fecha modificada.
Creo que esta es la mejor consulta para stamp_created y 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()
);
porque cuando el registro creado, stamp_created
debe llenarse por now()
y stamp_updated
debe llenarse por ''0000-00-00 00:00:00''
Este problema parece haberse resuelto en MySQL 5.6. Lo he notado hasta MySQL 5.5; aquí hay un código de ejemplo:
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;
Ejecutar esto en MySQL 5.5 da:
ERROR 1293 (HY000): Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause
Ejecutando esto en MySQL 5.6
0 row(s) affected 0.093 sec
Mi servidor web está atascado en la versión 5.1 de mysql, así que cualquier persona como yo que no tenga la opción de actualizar puede seguir estas instrucciones:
http://joegornick.com/2009/12/30/mysql-created-and-modified-date-fields/
Puedes tenerlos a ambos, solo quita el indicador "CURRENT_TIMESTAMP" en el campo creado. Siempre que cree un nuevo registro en la tabla, simplemente use "AHORA ()" para un valor.
O.
Por el contrario, elimine el indicador ''ACTUALIZAR ACTUALIZACIÓN ACTUALIZADA'' y envíe el AHORA () para ese campo. De esa manera, en realidad tiene más sentido.
Si decide que MySQL maneje la actualización de las marcas de tiempo, puede configurar un activador para actualizar el campo en Insertar.
CREATE TRIGGER <trigger_name> BEFORE INSERT ON <table_name> FOR EACH ROW SET NEW.<timestamp_field> = CURRENT_TIMESTAMP;
Referencia de MySQL: http://dev.mysql.com/doc/refman/5.0/en/triggers.html
De la documentación de MySQL 5.5 :
Una columna TIMESTAMP en una tabla puede tener la marca de tiempo actual como el valor predeterminado para inicializar la columna, como el valor de actualización automática, o ambos. No es posible que la marca de tiempo actual sea el valor predeterminado para una columna y el valor de actualización automática para otra columna.
Anteriormente, como máximo, una columna TIMESTAMP por tabla se podía inicializar o actualizar automáticamente a la fecha y hora actual. Esta restricción ha sido levantada. Cualquier definición de columna TIMESTAMP puede tener cualquier combinación de cláusulas DEFAULT CURRENT_TIMESTAMP y ON UPDATE CURRENT_TIMESTAMP. Además, estas cláusulas ahora se pueden usar con las definiciones de columna DATETIME. Para obtener más información, vea Inicialización automática y actualización para TIMESTAMP y DATETIME.
Hay un truco para tener ambas marcas de tiempo, pero con una pequeña limitación.
Puede usar solo una de las definiciones en una tabla. Cree ambas columnas de marca de tiempo de esta manera:
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()
);
Tenga en cuenta que es necesario ingresar null
en ambas columnas durante la 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)
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()
);
fuente: http://gusiev.com/2009/04/update-and-create-timestamps-with-mysql/