2016-06-16 6 views
1

ich eine Tabelle test mit 4 Spalten"auf Update CURRENT_TIMESTAMP" für nur eine Spalte in Mysql

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

Wenn ich unter Abfrage

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

Es updated_at ändern angewendet haben, wenn ich name oder visited ändern ,

Aber ich will es ändert sich nur wenn visited ändert.

Wie erreichen? danke für Ihre Hilfe.

Antwort

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

Es ist unglücklich über unsere aktuellen NULLs da drin sitzen, Fehler 1138:

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

ist das in Ordnung bringen lassen:

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

Wie ist das eine Antwort? Das OP möchte, dass das 'updated_at' aktualisiert wird, wenn' visited' nur aktualisiert wird. – JDrake

2

wie Sie das Handbuch Siehe Sounds brauche einen Auslöser, um das zu erreichen. Ihre Tabellendefinition Unter der Annahme, sieht so aus:

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

... Sie Ihr Ziel der Aktualisierung updated_at nur für die visited Säule mit einem Trigger, wie so erreichen kann.

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

Und Sie können es mit einem ziemlich geradlinigen Beispiel arbeiten sehen.

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

Übrigens, tut mir leid, wenn die Bedingung im Auslöser ein wenig wackelig aussieht. Aus irgendeinem Grund schnitt der Null-Safe-Operator ('<=>') nicht ab, und ich musste die Nullen manuell überprüfen und behandeln. Nicht schön, aber es funktioniert. – nasukkin