次のテーブルスキーマがあります。
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フィールドを手動で設定する必要がありますか?
テーブル内の1つのTIMESTAMP列には、列を初期化するためのデフォルト値、自動更新値、またはその両方として現在のタイムスタンプを含めることができます。 現在のタイムスタンプを1つの列のデフォルト値に、自動更新値を別の列に設定することはできません。
MySQL 5.6.5 の変更:
以前は、テーブルごとに最大で1つのTIMESTAMP列を自動的に初期化または現在の日時に更新することができました。 この制限は解除されました。TIMESTAMP列の定義には、DEFAULT CURRENT_TIMESTAMP句とON UPDATE CURRENT_TIMESTAMP句の任意の組み合わせを含めることができます。さらに、これらの句をDATETIME列定義で使用できるようになりました。詳細については、TIMESTAMPおよびDATETIMEの自動初期化および更新を参照してください。
トリックがあります 両方のタイムスタンプを使用しますが、少し制限があります。
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)
両方を持つことができ、作成されたフィールドの「CURRENT_TIMESTAMP」フラグを外すだけです。テーブルに新しいレコードを作成するたびに、値に「NOW()」を使用します。
または。
それどころか、「ON UPDATE CURRENT_TIMESTAMP」フラグを削除して、そのフィールドにNOW()を送信します。その方法は、実際にはより理にかなっています。
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
これは、トリガーを使用して、自動で柔軟な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);
しかし、ここがいいところです。
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)
)
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()
);
ソース:http://gusiev.com/2009/04/update-and-create-timestamps-with-mysql/
この問題は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
これはstamp_createdとstamp_updatedのより良いクエリだと思います
CREATE TABLE test_table(
id integer not null auto_increment primary key,
stamp_created TIMESTAMP DEFAULT now(),
stamp_updated TIMESTAMP DEFAULT '0000-00-00 00:00:00' ON UPDATE now()
);
レコードが作成されると、stamp_created
はnow()
で埋められ、stamp_updated
は'0000-00-00 00:00:00'
で埋められるためです。
Mysql 5.7.21の場合、次を使用して正常に動作します。
CREATE TABLE Posts
(modified_at
timestamp NOT NULL DEFAULT_CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP、created_at
timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP)
私のWebホストはバージョン5.1のmysqlでスタックしているため、アップグレードのオプションを持たない私のような人は以下の指示に従うことができます。
http://joegornick.com/2009/12/30/mysql-created-and-modified-date-fields/