【问题标题】:"on update CURRENT_TIMESTAMP" for only one column in mysqlmysql中只有一列的“更新CURRENT_TIMESTAMP”
【发布时间】:2016-10-17 19:36:16
【问题描述】:

我有一张桌子 test 有 4 列

id     name   visited      updated_at
1      abc    2016-03-20   2016-03-20 
2      xyz    2016-03-23   2016-03-23

当我应用以下查询时

ALTER TABLE `test` CHANGE `updated_at` `updated_at` TIMESTAMP on update 
CURRENT_TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00'; 

如果我更改 namevisited,它会更改 updated_at,

但我想它只有在visited 改变时才会改变。

如何做到这一点?感谢您的帮助。

【问题讨论】:

    标签: mysql sql timestamp


    【解决方案1】:
    drop table if exists `xyz1`;
    create table `xyz1`
    (   id int auto_increment primary key,
        theName varchar(20) not null,
        visited timestamp null, 
        updated_at timestamp null
    );
    insert `xyz1` (theName) values('abc'),('xyz');
    

    对我们当前的 NULL 坐在那里不满意,错误 1138:

    ALTER TABLE `xyz1` CHANGE `updated_at` `updated_at` TIMESTAMP 
    NOT NULL DEFAULT CURRENT_TIMESTAMP; 
    

    让我们解决这个问题:

    truncate table `xyz1`;
    
    ALTER TABLE `xyz1` CHANGE `updated_at` `updated_at` TIMESTAMP 
    DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP; 
    -- works
    
    insert `xyz1` (theName) values('abc'),('xyz');
    select * from `xyz1`;
    +----+---------+---------+---------------------+
    | id | theName | visited | updated_at          |
    +----+---------+---------+---------------------+
    |  1 | abc     | NULL    | 2016-06-16 14:39:38 |
    |  2 | xyz     | NULL    | 2016-06-16 14:39:38 |
    +----+---------+---------+---------------------+
    
    
    update `xyz1` set `theName`='xyz Smith' where id=2;
    select * from `xyz1`;
    +----+-----------+---------+---------------------+
    | id | theName   | visited | updated_at          |
    +----+-----------+---------+---------------------+
    |  1 | abc       | NULL    | 2016-06-16 14:39:38 |
    |  2 | xyz Smith | NULL    | 2016-06-16 14:41:04 |
    +----+-----------+---------+---------------------+
    

    参见手册Automatic Initialization and Updating

    【讨论】:

    • 这个答案怎么样? OP 希望仅在更新 visited 时更新 updated_at
    • 不是正确答案:updated_at在任何列更改时更新
    • 在 mariadb 上,它似乎不允许在单个列上使用 DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;...
    【解决方案2】:

    听起来你需要一个触发器来完成它。假设您的表定义如下所示:

    drop table if exists test;
    create table test(
      id BIGINT(20) PRIMARY KEY AUTO_INCREMENT,
      name VARCHAR(255) NOT NULL DEFAULT '',
      visited DATETIME NOT NULL DEFAULT '0000-00-00',
      updated_at DATETIME NOT NULL DEFAULT '0000-00-00'
    );
    

    ...您可以使用触发器实现仅更新 updated_at 列的 visited 的目标,就像这样。

    -- Create a trigger that will update the updated_at column iff visited changes.
    drop trigger if exists upd_test;
    delimiter //
    create trigger upd_test BEFORE UPDATE ON test
    FOR EACH ROW
    BEGIN
      IF (  (old.visited is not null and new.visited is not null and old.visited <> new.visited)
          OR (old.visited is null and new.visited is not null)
          OR (old.visited is not null and new.visited is null)  ) THEN
        SET NEW.updated_at = CURRENT_TIMESTAMP;
      END IF;
    END;//
    delimiter ;
    

    您可以通过一个相当简单的示例看到它。

    insert into test(name) values ("Bran"), ("Catelyn"), ("Daenerys"), ("Eddard");
    
    -- this statement will not cause updated_at to be updated
    update test
    set name = 'Jon'
    where name = 'Eddard';
    
    -- this statement will cause updated_at to be updated, via the trigger
    update test
    set visited = '2016-06-16'
    where name = 'Jon';
    

    【讨论】:

    • 顺便说一句,如果触发器中的条件看起来有点奇怪,很抱歉。出于某种原因,null-safe 运算符 (&lt;=&gt;) 没有删除它,我不得不手动检查和处理 null。不漂亮,但很管用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-12
    • 2011-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-30
    • 2011-06-21
    相关资源
    最近更新 更多