2011-07-05 6 views
9

"作成済み"と "更新済み"の両方の列を持つテーブルを作成したいとします。 「作成済み」列は挿入時に設定され、変更されることはありません。行「更新」は、行が更新されるたびに変更されます。次のINSERT文またはUPDATE文でこれらの列のいずれかを混乱させたくありません。だから私がこのようなものから始めると、私のCREATE TABLEステートメントはどうなるべきですか?1つのテーブル内に2つのMySQLタイムスタンプ列

CREATE TABLE IF NOT EXISTS `mydb`.`mytable` (
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY, 
    `updated` TIMESTAMP, 
    `created` TIMESTAMP, 
    `deleted` TINYINT DEFAULT 0, 
    `notes` TEXT DEFAULT '', 
    `description` VARCHAR(100) 
) TYPE=innodb; 

2つのTIMESTAMP列を持つ表の作成に問題があるようです。列がTIMESTAMPかDATETIMEかどうかは気にしません。挿入文や更新文の明示的な指示がなくても、それらの列をMySQLに取り込みたいだけです。このような

INSERT INTO `mydb`.`mytable` (notes,description) VALUES ('some note','some description'); 

と更新:

私はこのような挿入を行うことができるようにしたいと思い、明示的に「作成」列を設定したり、設定しなくても、

UPDATE `mydb`.`mytable` SET notes=CONCAT(notes,'some more notes') WHERE id=1; 

両方(またはinsert文またはupdate文の "updated"カラムをリセットします)。

+0

のようにタイムスタンプ列の順序を変更することです更新が発生するたびに「更新された」列が表示されます。私は完全な例で答えるだろうが、最近はPostgreSQLだけを使用しているので、MySQLでどのように処理されているのか分からない。しかし、私はMySQLのマニュアルが完全な構文を提供すると確信しています。 – Flimzy

+1

可能な複製[複数のTIMESTAMP列を持つ1つのMySQLテーブル](http://stackoverflow.com/questions/4851672/one-mysql-table-with-multiple-timestamp-columns) –

答えて

7

は、あなたのテーブルを作成するには、この方法を試してください。

CREATE TABLE IF NOT EXISTS db.test_table 
(
Id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, 
created DATETIME DEFAULT NULL, 
updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 
deleted TINYINT DEFAULT 0, 
notes TEXT DEFAULT NULL, 
description VARCHAR(100) 
) 

に留意されたいです。

このフィールドを自動的に更新できるようになりますatically。

そしてレコードを挿入する前に、トリガーのため、このいずれかを設定します。

DELIMITER $$ 

CREATE 
    /*[DEFINER = { user | CURRENT_USER }]*/ 
    TRIGGER `db`.`on_before_insert` BEFORE INSERT 
    ON `db`.`test_table` 
    FOR EACH ROW BEGIN 
    SET new.created = NOW();  
    END$$ 

DELIMITER ; 

次に、あなたが挿入するためにこれを使用することができます:

UPDATE db.test_table SET description = "Description 2" where Id=1 

INSERT INTO db.test_table(description) VALUES ("Description") 

をし、あなたの記録を更新し、作成および更新されたフィールドは適切に設定されます。

+0

あなたは、質問された質問に対する最も明白な答えに勝ちます。 @Dark Slipstreamの答えにはあまりにも多くのものがあります。 –

+0

タイムスタンプは、作成と更新の両方に使用する必要があります。バージョン5.5のmysqlでは、作成されたタイムスタンプをデフォルトのcurrent_timestampに設定することができます。また、更新時に更新されたタイムスタンプを設定し、デフォルトの現在のタイムスタンプに設定することができます。トリガは必要ありません。 –

0

残念ながら、MySQLでは、1つのテーブルに2つのTIMESTAMPカラムがありません。更新された列に対してはON UPDATE CURRENT_TIMESTAMPを使用し、NOW()関数を使用して手動で作成したセットを使用します。

+0

私の質問に記載されているように、 "created "私が明示的に避けようとしているのは手動です。 –

+0

正直言って私が間違っていて、それをやるより良い方法があると思っています! :) –

+0

Andreas Janssonは、テーブル定義だけではサポートされていませんが、まだ達成するのは非常に簡単です。 james_bondの答えを参照してください。 –

2

これを試してみてください:

CREATE TABLE IF NOT EXISTS mydb.mytable 
(
    id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, 
    updated DATETIME, 
    created TIMESTAMP, 
    deleted TINYINT DEFAULT 0, 
    notes TEXT DEFAULT '', 
    description VARCHAR(100) 
) TYPE=innodb; 

編集:トリガーを使用してください。

CREATE TRIGGER mytable_update 
BEFORE UPDATE ON mydb.mytable 
    FOR EACH ROW SET NEW.updated = NOW(); 
+0

DATETIMEがDEFAULT NOWになるとは思わない( –

+0

) 。他の解決策を探しています... –

+0

上記のコードで次のエラーが表示されます: –

1

ニュースフラッシュ: MySQLでは、TIMESTAMP列は常にnow()と行の他の列が更新されるたびに更新されている - これは、このデータ型の意図的な機能です。

DATETIME一方、この奇妙な動作はありません。これは完全に正常です。

答え:createdDATETIMEである必要がありますが、原因this bugに、あなたもこのように、トリガーが必要です

CREATE TABLE IF NOT EXISTS mytable (
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY, 
    `updated` TIMESTAMP, -- This will be updated to now(), if you don't set it or set it to null 
    `created` DATETIME NOT NULL, -- This will never be magically updated once written 
    `deleted` TINYINT DEFAULT 0, 
    `notes` TEXT DEFAULT '', 
    `description` VARCHAR(100) 
) TYPE=innodb; 

DELIMITER ~ 
CREATE TRIGGER mytable_insert_trigger 
BEFORE INSERT ON mytable 
FOR EACH ROW BEGIN 
    SET NEW.created = CURRENT_TIMESTAMP; 
END;~ 
DELIMITER ; 

insert into mytable (notes) values ('test'); 
select * from mytable; 
+----+---------------------+---------------------+---------+-------+-------------+ 
| id | updated    | created    | deleted | notes | description | 
+----+---------------------+---------------------+---------+-------+-------------+ 
| 1 | 2011-07-05 11:48:02 | 2011-07-05 11:48:02 |  0 | test | NULL  | 
+----+---------------------+---------------------+---------+-------+-------------+ 
+0

すべての更新時に '更新された'自動的にリセットされる素晴らしい方法があるように、問題は挿入時に 'created'を明示的にすべてのinsert文に追加することなくどのように設定するのかです。 –

+0

OK fine-edited to fix – Bohemian

+0

上記の@Dark Slipstreamの応答で述べたように、NOW()はDATETIMEでは機能しません。 –

1

代替は

OR

設定された第1の列のDEFAULT値あなたが「更新するにはONのUPDATEトリガを必要とするこの

ALTER TABLE `tblname` CHANGE `first_timestamp_column` 
    `first_timestamp_column` TIMESTAMP NOT NULL DEFAULT 0; 

Reference

関連する問題