web-dev-qa-db-fra.com

Pourquoi il ne peut y avoir qu'une seule colonne TIMESTAMP avec CURRENT_TIMESTAMP dans la clause DEFAULT?

Pourquoi il ne peut y avoir qu'une seule colonne TIMESTAMP avec CURRENT_TIMESTAMP dans la clause DEFAULT ou ON UPDATE?

CREATE TABLE `foo` (
  `ProductID` INT(10) UNSIGNED NOT NULL,
  `AddedDate` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `UpdatedDate` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=INNODB;

L'erreur qui en résulte:

Code d'erreur: 1293

Définition de table incorrecte; il ne peut y avoir qu'une seule colonne TIMESTAMP avec CURRENT_TIMESTAMP dans la clause DEFAULT ou ON UPDATE

176
ripper234

Cette limitation, qui était uniquement due à des raisons historiques, héritées du code, a été levée dans les versions récentes de MySQL:

Changements dans MySQL 5.6.5 (2012-04-10, Milestone 8)

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.

http://dev.mysql.com/doc/relnotes/mysql/5.6/en/news-5-6-5.html

166
augustin

Je me suis aussi demandé il y a longtemps. J'ai cherché un peu dans mon histoire et je pense que ce post: http://lists.mysql.com/internals/34919 représente la position semi-officielle de MySQL (avant l'intervention d'Oracle;))

En bref:

cette limitation provient uniquement de la manière dont cette fonctionnalité est actuellement implémentée dans le serveur et il n'y a aucune autre raison à son existence.

Donc, leur explication est "parce que c'est implémenté comme ça". Cela ne semble pas très scientifique. Je suppose que tout vient d'un vieux code. Ceci est suggéré dans le fil de discussion ci-dessus: "report de lorsque seul le premier champ d'horodatage a été défini/mis à jour automatiquement".

À votre santé!

39
Lachezar Balev

Nous pouvons donner une valeur par défaut pour l'horodatage afin d'éviter ce problème.

Ce message donne une solution de contournement détaillée: http://gusiev.com/2009/04/update-and-create-timestamps-with-mysql/

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 d'entrer des valeurs NULL dans les deux colonnes lors de "l'insertion":

mysql> insert into test_table(stamp_created, stamp_updated) values(null, null); 
Query OK, 1 row affected (0.06 sec)
mysql> select * from t5; 
+----+---------------------+---------------------+ 
| 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) 
34
Scarlett

En effet une faute d'implémentation.

L’approche native de MySQL consiste à mettre à jour vous-même une date de création (si vous en avez besoin) et à faire en sorte que MySQL s’inquiète pour le timestampupdate date ? update date : creation date comme suit:

CREATE TABLE tracked_data( 
  `data` TEXT,
  `timestamp`   TIMESTAMP,
  `creation_date` TIMESTAMP                                   
) ENGINE=INNODB; 

A la création Insérer NULL:

INSERT INTO tracked_data(`data`,`creation_date`) VALUES ('creation..',NULL);

Les valeurs NULL pour l'horodatage sont interpolées en tant que CURRENT_TIMESTAMP par défaut.

Dans MySQL, la première colonne TIMESTAMP d'une table obtient les attributs DEFAULT CURRENT_TIMESTAMP et ON UPDATE CURRENT_TIMESTAMP, si aucun attribut n'est fourni. C'est pourquoi la colonne TIMESTAMP avec les attributs doit venir en premier ou vous obtenez l'erreur décrite dans ce fil.

16
mooli
  1. Changer les types de données des colonnes en datetime
  2. Définir la gâchette

Tel que:

DROP TRIGGER IF EXISTS `update_tablename_trigger`;
DELIMITER //
CREATE TRIGGER `update_tablename_trigger` BEFORE UPDATE ON `tablename`
 FOR EACH ROW SET NEW.`column_name` = NOW()
//
DELIMITER ;
13
Feng-Chun Ting

Combinaison de différentes réponses:

Dans MySQL 5.5, _DEFAULT CURRENT_TIMESTAMP_ et _ON UPDATE CURRENT_TIMESTAMP_ ne peuvent pas être ajoutés sur DATETIME mais uniquement sur TIMESTAMP.

Règles:

1) Au plus une colonne TIMESTAMP par table pourrait être automatiquement (ou manuellement [ Mon ajout ]) initialisée ou mise à jour à la date et à l’heure actuelles. (Docs MySQL).

Ainsi, un seul TIMESTAMP peut avoir _CURRENT_TIMESTAMP_ dans la clause DEFAULT ou _ON UPDATE_

2) La première colonne _NOT NULL_ TIMESTAMP sans une valeur explicite DEFAULT telle que _created_date timestamp default '0000-00-00 00:00:00'_ recevra implicitement un _DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP_ et les colonnes TIMESTAMP suivantes ne peuvent donc pas être données _CURRENT_TIMESTAMP_ sur DEFAULT ou _ON UPDATE_ clause

_CREATE TABLE `address` (
  `id` int(9) NOT NULL AUTO_INCREMENT,
  `village` int(11) DEFAULT NULL,
    `created_date` timestamp default '0000-00-00 00:00:00', 

    -- Since explicit DEFAULT value that is not CURRENT_TIMESTAMP is assigned for a NOT NULL column, 
    -- implicit DEFAULT CURRENT_TIMESTAMP is avoided.
    -- So it allows us to set ON UPDATE CURRENT_TIMESTAMP on 'updated_date' column.
    -- How does setting DEFAULT to '0000-00-00 00:00:00' instead of CURRENT_TIMESTAMP help? 
    -- It is just a temporary value.
    -- On INSERT of explicit NULL into the column inserts current timestamp.

-- `created_date` timestamp not null default '0000-00-00 00:00:00', // same as above

-- `created_date` timestamp null default '0000-00-00 00:00:00', 
-- inserting 'null' explicitly in INSERT statement inserts null (Ignoring the column inserts the default value)! 
-- Remember we need current timestamp on insert of 'null'. So this won't work. 

-- `created_date` timestamp null , // always inserts null. Equally useless as above. 

-- `created_date` timestamp default 0, // alternative to '0000-00-00 00:00:00'

-- `created_date` timestamp, 
-- first 'not null' timestamp column without 'default' value. 
-- So implicitly adds DEFAULT CURRENT_TIMESTAMP and ON UPDATE CURRENT_TIMESTAMP. 
-- Hence cannot add 'ON UPDATE CURRENT_TIMESTAMP' on 'updated_date' column.


   `updated_date` timestamp null on update current_timestamp,

  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=132 DEFAULT CHARSET=utf8;
_

_INSERT INTO address (village,created_date) VALUES (100,null);
_

_mysql> select * from address;
+-----+---------+---------------------+--------------+
| id  | village | created_date        | updated_date |
+-----+---------+---------------------+--------------+
| 132 |     100 | 2017-02-18 04:04:00 | NULL         |
+-----+---------+---------------------+--------------+
1 row in set (0.00 sec)
_

_UPDATE address SET village=101 WHERE village=100;
_

_mysql> select * from address;
+-----+---------+---------------------+---------------------+
| id  | village | created_date        | updated_date        |
+-----+---------+---------------------+---------------------+
| 132 |     101 | 2017-02-18 04:04:00 | 2017-02-18 04:06:14 |
+-----+---------+---------------------+---------------------+
1 row in set (0.00 sec)
_

Autre option (mais _updated_date_ est la première colonne):

_CREATE TABLE `address` (
  `id` int(9) NOT NULL AUTO_INCREMENT,
  `village` int(11) DEFAULT NULL,
  `updated_date` timestamp null on update current_timestamp,
  `created_date` timestamp not null , 
  -- implicit default is '0000-00-00 00:00:00' from 2nd timestamp onwards

  -- `created_date` timestamp not null default '0000-00-00 00:00:00'
  -- `created_date` timestamp
  -- `created_date` timestamp default '0000-00-00 00:00:00'
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=132 DEFAULT CHARSET=utf8;
_
1
user104309

Un correctif pour vous pourrait être de le mettre sur le champ UpdatedDate et d’avoir un déclencheur qui met à jour le champ AddedDate avec la valeur UpdatedDate uniquement si AddedDate est null.

1
HLGEM

Essaye ça:

CREATE TABLE `test_table` (
`id` INT( 10 ) NOT NULL,
`created_at` TIMESTAMP NOT NULL DEFAULT 0,
`updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE = INNODB;
0
Shoaib Qureshi

C'est la limitation de la version MYSQL 5.5. Vous devez mettre à jour la version 5.6.

Error

J'obtenais cette erreur en ajoutant une table dans MYSQL

Définition de table incorrecte; il ne peut y avoir qu'une seule colonne TIMESTAMP avec CURRENT_TIMESTAMP dans la clause DEFAULT ou ON UPDATE Ma nouvelle MYSQL

ressemble à ceci:

create table nom_table (col1 int (5) clé primaire auto_increment, col2 varchar (300), col3 varchar (500), col4 int (3), col5 tinyint (2), col6 horodatage default current_timestamp, col7 timestamp par défaut current_timestamp sur current_timestamp sur update, col8 tinyint (1) par défaut 0, col9 tinyint (1) par défaut 1);

Après un certain temps de lecture sur les modifications apportées aux différentes versions de MYSQL et sur Google. J'ai découvert que certaines modifications avaient été apportées à MYSQL version 5.6 par rapport à la version 5.5.

Cet article vous aidera à résoudre le problème. http://www.oyewiki.com/MYSQL/Incorrect-table-definition-there-can-be-only-one-timestamp-column

0
Ankur Rastogi