132

次のテーブル スキーマがあります。

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;

次のエラーで失敗します。

ERROR 1293 (HY000): Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause.

私の質問は、これらのフィールドの両方を使用できますか? または、各トランザクション中に LastUpdated フィールドを手動で設定する必要がありますか?

4

12 に答える 12

136

MySQL 5.5のドキュメントから:

テーブル内の 1 つの TIMESTAMP 列は、列を初期化するためのデフォルト値、自動更新値、またはその両方として、現在のタイムスタンプを持つことができます。現在のタイムスタンプをある列のデフォルト値にして、別の列の自動更新値にすることはできません。

MySQL 5.6.5での変更:

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

于 2008-11-06T04:52:08.260 に答える
89

両方のタイムスタンプを設定するためのトリックがありますが、少し制限があります。

1つのテーブルで使用できる定義は1つだけです。次のように両方のタイムスタンプ列を作成します。

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() 
); 

nullの間に両方の列に入力する必要があることに注意してください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)  
于 2009-04-30T15:48:48.530 に答える
27

MySQL でタイムスタンプの更新を処理することにした場合は、挿入時にフィールドを更新するトリガーを設定できます。

CREATE TRIGGER <trigger_name> BEFORE INSERT ON <table_name> FOR EACH ROW SET NEW.<timestamp_field> = CURRENT_TIMESTAMP;

MySQL リファレンス: http://dev.mysql.com/doc/refman/5.0/en/triggers.html

于 2011-06-24T15:53:26.387 に答える
27

作成されたフィールドの「CURRENT_TIMESTAMP」フラグを外すだけで、両方を持つことができます。テーブルに新しいレコードを作成するときはいつでも、値に「NOW()」を使用してください。

または。

逆に、「ON UPDATE CURRENT_TIMESTAMP」フラグを削除し、そのフィールドの NOW() を送信します。その方法は実際にはより理にかなっています。

于 2008-11-06T04:45:36.837 に答える
23

これは、トリガーを使用して自動で柔軟な createDate/lastModified フィールドを作成する方法です。

まず、次のように定義します。

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`),
)

次に、次のトリガーを追加します。

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);
  • createDate または lastModified を指定せずに挿入すると、それらは等しくなり、現在のタイムスタンプに設定されます。
  • createDate または lastModified を指定せずに更新すると、lastModified は現在のタイムスタンプに設定されます。

しかし、ここに良い部分があります:

  • 挿入すると、現在の timestamp よりも古い createDateを指定できるため、古い時刻からのインポートがうまく機能します (lastModified は createDate と等しくなります)。
  • 更新する場合、以前の値よりも古い lastModifiedを指定でき('0000-00-00 00:00:00' は適切に機能します)、表面的な変更を行う場合 (コメントのタイプミスを修正する場合) にエントリを更新できます。 ) で、古い lastModified日付を保持したい場合。これは lastModified 日付を変更しません。
于 2013-05-07T08:14:17.300 に答える
22

MySQL 5.6 の時点では、簡単です...試してみてください:

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)
)
于 2013-12-03T09:45:59.667 に答える
4

この問題は、MySQL 5.6 で解決されたようです。MySQL 5.5 まではこれに気付きました。ここにコード例があります:

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;

これを MySQL 5.5 で実行すると、次のようになります。

ERROR 1293 (HY000): Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause

これを MySQL 5.6 で実行する

0 row(s) affected   0.093 sec
于 2013-11-14T17:30:05.813 に答える