Perché può esistere una sola colonna TIMESTAMP con CURRENT_TIMESTAMP nella clausola DEFAULT?

Perché può esistere una sola colonna TIMESTAMP con CURRENT_TIMESTAMP nella clausola DEFAULT o 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’errore che risulta:

Codice di errore: 1293

Definizione della tabella errata; può esserci una sola colonna TIMESTAMP con CURRENT_TIMESTAMP nella clausola DEFAULT o ON UPDATE

Questa limitazione, che era dovuta solo a ragioni storiche e legacy del codice, è stata risolta nelle recenti versioni di MySQL:

Cambiamenti in MySQL 5.6.5 (2012-04-10, Milestone 8)

In precedenza, al massimo una colonna TIMESTAMP per tabella poteva essere inizializzata automaticamente o aggiornata alla data e ora correnti. Questa restrizione è stata revocata. Qualsiasi definizione di colonna TIMESTAMP può avere qualsiasi combinazione di clausole DEFAULT CURRENT_TIMESTAMP e ON UPDATE CURRENT_TIMESTAMP. Inoltre, ora queste clausole possono essere utilizzate con le definizioni di colonna DATETIME. Per ulteriori informazioni, vedere Inizializzazione e aggiornamento automatici per TIMESTAMP e DATETIME.

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

Anch’io me lo sono chiesto molto tempo fa. Ho cercato un po ‘nella mia storia e penso che questo post: http://lists.mysql.com/internals/34919 rappresenti la posizione semi-ufficiale di MySQL (prima dell’intervento di Oracle;))

In breve:

questa limitazione deriva solo dal modo in cui questa funzione è attualmente implementata nel server e non ci sono altri motivi per la sua esistenza.

Quindi la loro spiegazione è “perché è implementata in questo modo”. Non sembra molto scientifico. Immagino che tutto provenga da un vecchio codice. Questo è suggerito nella discussione sopra: “carry-over da quando solo il primo campo timestamp è stato auto-impostato / aggiornato”.

Saluti!

Possiamo dare un valore predefinito per il timestamp per evitare questo problema.

Questo post fornisce una soluzione dettagliata: 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() ); 

Si noti che è necessario inserire valori nulli in entrambe le colonne durante “insert”:

 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) 

Effettivamente un difetto di implementazione.

L’approccio nativo in MySQL è aggiornare una data di creazione da soli (se ne hai bisogno) e avere MySQL preoccupato della update date ? update date : creation date dell’orario update date ? update date : creation date update date ? update date : creation date modo:

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

Alla creazione Inserisci NULL:

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

I valori NULL per timestamp sono interperted come CURRENT_TIMESTAMP per impostazione predefinita.

In MySQL, la prima colonna TIMESTAMP di una tabella ottiene sia l’attributo DEFAULT CURRENT_TIMESTAMP che ON UPDATE CURRENT_TIMESTAMP , se non viene fornito alcun attributo. questo è il motivo per cui la colonna TIMESTAMP con attributi deve venire prima o si ottiene l’errore descritto in questo thread.

  1. Cambia i tipi di dati di colonne in data / ora
  2. Imposta trigger

Ad esempio:

 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 ; 

Beh, una soluzione per voi potrebbe essere quella di metterlo sul campo UpdateDate e avere un trigger che aggiorna il campo AddedDate con il valore UpdateDate solo se AddedDate è null.

Combinando varie risposte:

In MySQL 5.5, DEFAULT CURRENT_TIMESTAMP e ON UPDATE CURRENT_TIMESTAMP non possono essere aggiunti su DATETIME ma solo su TIMESTAMP .

Regole:

1) al massimo una colonna TIMESTAMP per tabella potrebbe essere automaticamente (o manualmente [ My addition ]) inizializzata o aggiornata alla data e ora correnti. (Documenti MySQL).

Quindi solo un TIMESTAMP può avere CURRENT_TIMESTAMP nella clausola DEFAULT o ON UPDATE

2) La prima colonna NOT NULL TIMESTAMP senza un valore DEFAULT esplicito come created_date timestamp default '0000-00-00 00:00:00' verrà implicitamente assegnata a DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP e quindi le colonne TIMESTAMP successive non possono essere date CURRENT_TIMESTAMP su DEFAULT o ON UPDATE clausola ON UPDATE

 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) 

Altra opzione (ma updated_date è la prima colonna):

 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; 

Prova questo:

 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; 

Questa è la limitazione nella versione MYSQL 5.5. È necessario aggiornare la versione a 5.6.

 Error 

Stavo ottenendo questo errore nell’aggiunta di una tabella in MYSQL

Definizione della tabella errata; può esserci una sola colonna TIMESTAMP con CURRENT_TIMESTAMP nella clausola DEFAULT o ON UPDATE My new MYSQL

tavolo sembra qualcosa del genere.

create table nome_tabella (col1 int (5) auto_increment chiave primaria, col2 varchar (300), col3 varchar (500), col4 int (3), col5 tinyint (2), col6 timestamp default current_timestamp, col7 timestamp default current_timestamp su update current_timestamp, col8 tinyint (1) default 0, col9 tinyint (1) default 1);

Dopo qualche tempo di lettura dei cambiamenti in diverse versioni di MYSQL e alcuni dei googling. Ho scoperto che c’erano alcune modifiche apportate a MYSQL versione 5.6 rispetto alla versione 5.5.

Questo articolo ti aiuterà a risolvere il problema. http://www.oyewiki.com/MYSQL/Incorrect-table-definition-there-can-be-only-one-timestamp-column