2011-07-05 45 views
9

Tôi muốn tạo bảng có cả cột cho "được tạo" và cột khác cho "được cập nhật". Cột "được tạo" sẽ được đặt ở vị trí chèn và không bao giờ thay đổi. Cột "cập nhật" sẽ thay đổi mỗi khi một hàng được cập nhật. Tôi không muốn gây rối với một trong hai cột này trong các câu lệnh INSERT hoặc UPDATE tiếp theo. Vậy câu lệnh CREATE TABLE của tôi trông như thế nào nếu tôi bắt đầu với một cái gì đó như thế này?Hai cột dấu thời gian của MySQL trong một bảng

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; 

Tôi dường như gặp sự cố khi tạo bảng bằng hai cột TIMESTAMP. Tôi không quan tâm nếu các cột là TIMESTAMP hoặc DATETIME hoặc bất cứ điều gì, tôi chỉ muốn chúng được điền bởi MySQL mà không có hướng dẫn rõ ràng từ các câu lệnh chèn hoặc cập nhật.

Tôi muốn để có thể làm chèn như thế này:

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

và cập nhật như thế này:

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

cả mà không cần phải thiết lập một cách rõ ràng cột "tạo ra" hoặc thiết lập (hoặc đặt lại) cột "được cập nhật" trong câu lệnh chèn hoặc cập nhật.

+0

Bạn cần một ON UPDATE kích hoạt để cập nhật " cập nhật "cột mỗi lần cập nhật xảy ra. Tôi muốn trả lời với một ví dụ hoàn chỉnh, nhưng tôi không biết làm thế nào được thực hiện trong MySQL, vì tôi chỉ sử dụng PostgreSQL những ngày này. Nhưng tôi chắc rằng hướng dẫn sử dụng MySQL sẽ cung cấp cho bạn cú pháp đầy đủ. – Flimzy

+1

bản sao có thể có của [Một bảng Mysql với nhiều cột TIMESTAMP] (http://stackoverflow.com/questions/4851672/one-mysql-table-with-multiple-timestamp-columns) –

Trả lời

7

Hãy thử một trong này để tạo bảng của bạn:

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

Lưu ý rằng

updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP 

sẽ cho phép tự động cập nhật trường này về cơ bản.

Và thiết lập này cho một kích hoạt trước khi ghi chèn:

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 ; 

Sau đó, bạn có thể sử dụng để chèn:

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

và cập nhật hồ sơ của bạn

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

Và các trường được tạo và cập nhật của bạn sẽ được đặt một cách thích hợp.

+0

bạn giành được câu trả lời rõ ràng nhất cho câu hỏi đã được hỏi. @Dark Slipstream của câu trả lời có rất nhiều để cung cấp quá mặc dù. –

+0

Tôi nghĩ rằng dấu thời gian nên được sử dụng cho cả được tạo và cập nhật. Với phiên bản 5.5 của mysql bạn có thể đặt dấu thời gian được tạo thành mặc định thành current_timestamp và bạn có thể đặt dấu thời gian được cập nhật để tự động cập nhật trên các cập nhật VÀ đặt mặc định thành dấu thời gian hiện tại. Và không có kích hoạt là cần thiết. –

0

Thật không may, MySQL không cho phép bạn có hai cột TIMESTAMP trong một bảng. Tôi sẽ sử dụng ON UPDATE CURRENT_TIMESTAMP cho cột được cập nhật và thiết lập được tạo theo cách thủ công bằng cách sử dụng hàm NOW().

+0

Như đã nêu trong câu hỏi của tôi, thiết lập "đã tạo "theo cách thủ công là những gì tôi rõ ràng muốn tránh. –

+0

Tôi thành thật hy vọng mình sai và có cách làm tốt hơn! :) –

+0

Andreas Jansson, mặc dù nó không được hỗ trợ với các định nghĩa bảng một mình, điều này vẫn còn rất dễ thực hiện. Xem câu trả lời của james_bond. –

2

Hãy thử điều này:

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; 

Sửa: Sử dụng một cò.

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

Tôi không nghĩ rằng DATETIME có thể là DEFAULT NOW() –

+0

Bạn phải .. tìm kiếm một giải pháp khác ... –

+0

Tôi nhận được lỗi sau với mã ở trên: –

1

Tin tức flash: Trong mysql, TIMESTAMP cột luôn được cập nhật với now() mỗi khi bất kỳ cột khác ở hàng được cập nhật - đây là một tính năng cố ý của datatype này.

DATETIME mặt khác không có hành vi kỳ lạ này - nó hoàn toàn bình thường.

Câu trả lời: created phải DATETIME, nhưng do this bug, bạn cũng cần một kích hoạt, như thế này:

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

cũng giống như có một cách tiện lợi để có được 'cập nhật' tự động thiết lập lại ở mọi cập nhật, vấn đề là làm thế nào để có được' tạo' đặt lúc chèn mà không cần thêm nó vào mỗi câu lệnh chèn. –

+0

OK được chỉnh sửa để sửa lỗi – Bohemian

+0

Như đã lưu ý trong phản hồi của @Dark Slipstream ở trên, NOW() không hoạt động với DATETIME. –

1

thay thế là thay đổi thứ tự của cột timestamp

HOẶC

thiết lập cột đầu tiên giá trị DEFAULT như thế này

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

Reference

Các vấn đề liên quan