2016-06-16 2 views
1

У меня есть одна таблица test с 4-мя колоннами«на обновление CURRENT_TIMESTAMP» только для одного столбца в MySQL

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'; 

Это изменить updated_at, если я изменю name или visited ,

Но я хочу, чтобы он менялся, только если visited изменений.

Как достичь этого? Спасибо за вашу помощь.

ответ

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

+0

Как это ответить? OP хочет обновить 'updated_at', когда обновляется' visit'. – JDrake

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'; 
+0

Кстати, извините, если условный сигнал в триггере выглядит немного завораживающим. По какой-то причине нуль-безопасный оператор ('<=>') не разрезал его, и мне пришлось вручную проверять и обрабатывать нули. Не очень, но это работает. – nasukkin

Смежные вопросы