webentwicklung-frage-antwort-db.com.de

Warum kann es in der DEFAULT-Klausel nur eine TIMESTAMP-Spalte mit CURRENT_TIMESTAMP geben?

Warum kann es in DEFAULT- oder ON UPDATE-Klausel nur eine TIMESTAMP-Spalte mit CURRENT_TIMESTAMP geben?

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;

Der daraus resultierende Fehler:

Fehlercode: 1293

Falsche Tabellendefinition; In der Klausel DEFAULT oder ON UPDATE kann es nur eine TIMESTAMP-Spalte mit CURRENT_TIMESTAMP geben

176
ripper234

Diese Einschränkung, die nur aus historischen Gründen aufgrund von Code-Legacy erfolgte, wurde in neueren Versionen von MySQL aufgehoben:

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

Bisher konnte höchstens eine TIMESTAMP-Spalte pro Tabelle automatisch initialisiert oder auf das aktuelle Datum und die aktuelle Uhrzeit aktualisiert werden. Diese Einschränkung wurde aufgehoben. Jede TIMESTAMP-Spaltendefinition kann eine beliebige Kombination von DEFAULT CURRENT_TIMESTAMP- und ON UPDATE CURRENT_TIMESTAMP-Klauseln enthalten. Außerdem können diese Klauseln jetzt mit DATETIME-Spaltendefinitionen verwendet werden. Weitere Informationen finden Sie unter Automatische Initialisierung und Aktualisierung für TIMESTAMP und DATETIME.

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

166
augustin

Ich habe mich auch schon vor langer Zeit gefragt. Ich habe ein bisschen in meiner Geschichte gesucht und ich denke, dass dieser Beitrag: http://lists.mysql.com/internals/34919 den semi-offiziellen darstellt Position von MySQL (vor dem Eingreifen von Oracle;))

Zusamenfassend:

diese Einschränkung ergibt sich nur aus der Art und Weise, in der diese Funktion derzeit auf dem Server implementiert ist, und es gibt keine weiteren Gründe für ihre Existenz.

Ihre Erklärung lautet also "weil es so implementiert ist". Klingt nicht sehr wissenschaftlich. Ich denke, alles kommt von einem alten Code. Dies wird in dem obigen Thread vorgeschlagen: "Übertragung von wann nur das erste Zeitstempelfeld automatisch gesetzt/aktualisiert wurde".

Prost!

39
Lachezar Balev

Wir können einen Standardwert für den Zeitstempel angeben, um dieses Problem zu vermeiden.

Dieser Beitrag bietet eine detaillierte Problemumgehung: 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() 
);

Beachten Sie, dass beim "Einfügen" Nullen in beide Spalten eingegeben werden müssen:

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

In der Tat ein Implementierungsfehler.

Der systemeigene Ansatz in MySQL besteht darin, ein Erstellungsdatum selbst zu aktualisieren (falls erforderlich) und MySQL sich Gedanken über den Zeitstempelupdate date ? update date : creation date Zu machen:

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

Bei der Erstellung NULL einfügen:

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

NULL-Werte für Zeitstempel werden standardmäßig als CURRENT_TIMESTAMP interpretiert.

In MySQL erhält die erste TIMESTAMP-Spalte einer Tabelle sowohl das Attribut DEFAULT CURRENT_TIMESTAMP Als auch das Attribut ON UPDATE CURRENT_TIMESTAMP, Wenn keine Attribute dafür angegeben sind. Aus diesem Grund muss die TIMESTAMP-Spalte mit Attributen an erster Stelle stehen, da sonst der in diesem Thread beschriebene Fehler angezeigt wird.

16
mooli
  1. Ändern Sie die Datentypen von Spalten in datetime
  2. Trigger setzen

Sowie:

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

Verschiedene Antworten kombinieren:

In MySQL 5.5 können DEFAULT CURRENT_TIMESTAMP Und ON UPDATE CURRENT_TIMESTAMP Nicht zu DATETIME hinzugefügt werden, sondern nur zu TIMESTAMP.

Regeln:

1) Höchstens eine TIMESTAMP Spalte pro Tabelle kann automatisch (oder manuell [ Mein Zusatz ]) initialisiert oder auf das aktuelle Datum aktualisiert werden und Zeit. (MySQL Docs).

Daher kann nur ein TIMESTAMPCURRENT_TIMESTAMP In der DEFAULT - oder ON UPDATE - Klausel haben

2) Der ersten NOT NULLTIMESTAMP Spalte ohne expliziten DEFAULT Wert wie created_date timestamp default '0000-00-00 00:00:00' Wird implizit ein DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP Und damit ein nachfolgender TIMESTAMP-Spalten können in der Klausel DEFAULT oder CURRENT_TIMESTAMP nicht mit ON UPDATE angegeben werden

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)

Andere Option (Aber updated_date Ist die erste Spalte):

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

Nun, eine Lösung für Sie könnte darin bestehen, es in das Feld "UpdatedDate" einzufügen und einen Auslöser zu haben, der das Feld "AddedDate" nur dann mit dem Wert "UpdatedDate" aktualisiert, wenn "AddedDate" null ist.

1
HLGEM

Versuche dies:

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

Dies ist die Einschränkung in der MYSQL 5.5-Version. Sie müssen die Version auf 5.6 aktualisieren.

Error

Ich habe diesen Fehler beim Hinzufügen einer Tabelle in MYSQL erhalten

Falsche Tabellendefinition; Es kann nur eine TIMESTAMP-Spalte mit CURRENT_TIMESTAMP in DEFAULT- oder ON UPDATE-Klausel My new MYSQL geben

Die Tabelle sieht ungefähr so ​​aus.

create table Tabellenname (col1 int (5) Auto_Increment-Primärschlüssel, col2 varchar (300), col3 varchar (500), col4 int (3), col5 tinyint (2), col6 timestamp default current_timestamp, col7 timestamp default current_timestamp on update current_timestamp col8 tinyint (1) default 0, col9 tinyint (1) default 1);

Nach einiger Zeit über Änderungen in verschiedenen MYSQL-Versionen und einige der googeln zu lesen. Ich fand heraus, dass es einige Änderungen gab, die in MYSQL Version 5.6 gegenüber Version 5.5 vorgenommen wurden.

Dieser Artikel hilft Ihnen, das Problem zu beheben. http://www.oyewiki.com/MYSQL/Incorrect-table-definition-there-can-be-on-timestamp-column

0
Ankur Rastogi