185

DEFAULT または ON UPDATE 句で CURRENT_TIMESTAMP を持つ TIMESTAMP 列が 1 つしか存在できないのはなぜですか?

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;

結果のエラー:

エラーコード: 1293

テーブル定義が正しくありません。DEFAULT または ON UPDATE 句で CURRENT_TIMESTAMP を持つ TIMESTAMP 列は 1 つだけ存在できます

4

9 に答える 9

177

この制限は、歴史的なコード レガシーの理由のみによるものでしたが、MySQL の最近のバージョンでは解除されました。

MySQL 5.6.5 の変更 (2012-04-10、マイルストーン 8)

以前は、テーブルごとに最大で 1 つの TIMESTAMP 列を現在の日付と時刻に自動的に初期化または更新できました。この制限は解除されました。TIMESTAMP 列の定義には、DEFAULT CURRENT_TIMESTAMP 句と ON UPDATE CURRENT_TIMESTAMP 句の任意の組み合わせを含めることができます。さらに、これらの句を DATETIME 列定義で使用できるようになりました。詳細については、TIMESTAMP および DATETIME の自動初期化と自動更新を参照してください。

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

于 2013-07-05T23:40:41.850 に答える
40

私も昔からそう思っていました。私は自分の歴史を少し調べましたが、この投稿は次のように思います: http://lists.mysql.com/internals/34919は MySQL の半公式の立場を表しています (Oracle の介入前;))

要するに:

この制限は、この機能が現在サーバーに実装されている方法にのみ起因するものであり、この機能が存在する理由は他にありません。

したがって、彼らの説明は「このように実装されているため」です。とても科学的に聞こえません。それはすべて古いコードから来ていると思います。これは、上記のスレッドで提案されています:「最初のタイムスタンプ フィールドのみが自動設定/更新されたときからのキャリーオーバー」。

乾杯!

于 2010-12-20T13:20:16.447 に答える
38

この問題を回避するために、タイムスタンプのデフォルト値を指定できます。

この投稿では、詳細な回避策を示しています: 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() 
);

「挿入」中に両方の列にヌルを入力する必要があることに注意してください。

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) 
于 2011-11-16T07:06:00.923 に答える
16

確かに実装の誤り。

MySQLのネイティブなアプローチは、作成日を自分で更新し(必要な場合)、MySQLにタイムスタンプ update date ? update date : creation dateについて次のように心配させることです。

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

作成時にNULLを挿入します。

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

タイムスタンプのNULL値は、デフォルトでCURRENT_TIMESTAMPとして解釈されます。

MySQLでは、テーブルの最初のTIMESTAMP列は、属性が指定されていない場合、属性DEFAULT CURRENT_TIMESTAMPON UPDATE CURRENT_TIMESTAMP属性の両方を取得します。これが、属性を持つTIMESTAMP列が最初に来る必要がある理由です。そうしないと、このスレッドで説明されているエラーが発生します。

于 2012-11-24T18:23:50.647 に答える
14
  1. 列のデータ型を日時に変更します
  2. トリガーを設定する

そのような:

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 ;
于 2011-04-21T12:20:55.587 に答える
3

さまざまな答えを組み合わせる:

MySQL 5.5 では、DEFAULT CURRENT_TIMESTAMPON UPDATE CURRENT_TIMESTAMP追加できず、 にDATETIMEのみ追加できますTIMESTAMP

ルール:

1)TIMESTAMPテーブルごとに最大で1つの列を自動的に(または手動で[私の追加])初期化または現在の日時に更新できます。(MySQL ドキュメント)。

そのため、 inまたは句TIMESTAMPを使用できるのは1 つだけですCURRENT_TIMESTAMPDEFAULTON UPDATE

2) のようなNOT NULL TIMESTAMP明示的なDEFAULT値のない最初の列にcreated_date timestamp default '0000-00-00 00:00:00'は暗黙的に a が与えられるDEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMPため、後続の列をor節TIMESTAMPに与えることはできませんCURRENT_TIMESTAMPDEFAULTON 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)

その他のオプション (ただしupdated_date、最初の列です):

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;
于 2017-02-17T22:44:38.737 に答える
1

それを UpdatedDate フィールドに配置し、AddedDate が null の場合にのみ UpdatedDate 値で AddedDate フィールドを更新するトリガーを設定することで、問題を解決できます。

于 2010-12-20T17:07:36.347 に答える
0

これは MYSQL 5.5 バージョンの制限です。バージョンを 5.6 に更新する必要があります。

Error

MYSQL でテーブルを追加する際にこのエラーが発生しました

テーブル定義が正しくありません。DEFAULT または ON UPDATE 句で CURRENT_TIMESTAMP を持つ TIMESTAMP 列は 1 つしか存在できません My new MYSQL

テーブルはこんな感じ。

テーブル table_name を作成 (col1 int(5) auto_increment 主キー、col2 varchar(300)、col3 varchar(500)、col4 int(3)、col5 tinyint(2)、col6 タイムスタンプのデフォルト current_timestamp、col7 タイムスタンプのデフォルト current_timestamp 更新 current_timestamp で、 col8 tinyint(1) デフォルト 0、col9 tinyint(1) デフォルト 1);

さまざまなMYSQLバージョンの変更といくつかのグーグルについて読んだ後。MYSQL バージョン 5.6 では、バージョン 5.5 に対していくつかの変更が加えられていることがわかりました。

この記事は、問題の解決に役立ちます。 http://www.oyewiki.com/MYSQL/Incorrect-table-definition-there-can-be-only-one-timestamp-column

于 2016-07-31T20:08:42.613 に答える
0

これを試して:

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;
于 2014-01-30T11:03:06.313 に答える