Bạn có thể sử dụng các cấu trúc sql bình thường trong TRÊN KHÓA DUPLICATE cú pháp. Vì vậy, để thực hiện cập nhật có điều kiện trong khi chèn, bạn có thể làm như sau:
INSERT INTO tbl (hat, mittens, name)
VALUES ('yellow','purple','jimmy')
ON DUPLICATE KEY UPDATE name = CASE WHEN name <> VALUES(name)
THEN VALUES(name) ELSE name END;
Điều này sẽ thay đổi giá trị thành những gì bạn đã cung cấp cho câu lệnh chèn khi nó khác với những gì trong hàng và sẽ đặt giá trị thành giá trị đã có nếu nó không thay đổi và sẽ dẫn đến việc MySQL không thực hiện bất kỳ điều gì đối với việc bảo toàn hàng dấu thời gian last_update như Quassnoi đã chỉ ra.
Nếu bạn muốn chắc chắn 100% rằng bạn không dựa vào hành vi của MySQL, nơi nó không cập nhật một hàng nếu bạn đặt một giá trị cho chính nó, bạn có thể làm như sau để buộc dấu thời gian:
INSERT INTO tbl (hat, mittens, name)
VALUES ('yellow','purple','jimmy')
ON DUPLICATE KEY UPDATE name = CASE WHEN name <> VALUES(name)
THEN VALUES(name) ELSE name END
, last_update = CASE WHEN name <> VALUES(name)
THEN now() ELSE last_update END;
Điều này sẽ chỉ cập nhật last_update
tới now()
khi tên đã thay đổi khác, nó sẽ yêu cầu MySQL giữ lại giá trị của last_update
.
Ngoài ra, trong phần ON DUPLICATE KEY của câu lệnh, bạn có thể tham chiếu đến các cột trong bảng theo tên của chúng và bạn có thể nhận các giá trị mà bạn đã cung cấp cho phần chèn giá trị câu lệnh bằng cách sử dụng href GIÁ TRỊ (column_name) chức năng.
Sau đây là nhật ký cho thấy rằng câu lệnh cuối cùng được cung cấp hoạt động ngay cả trên 4.1 trong đó các câu lệnh khác không hoạt động do một lỗi đã được sửa trong phiên bản 5.0.
C:\mysql\bin>mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 1 to server version: 4.1.22-community
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql> show databases;
+----------+
| Database |
+----------+
| mysql |
| test |
+----------+
2 rows in set (0.00 sec)
mysql> use test;
Database changed
mysql> show tables;
Empty set (0.00 sec)
mysql> CREATE TABLE `tbl` (
-> `hat` varchar(11) default NULL,
-> `mittens` varchar(11) default NULL,
-> `name` varchar(11) default NULL,
-> `stamp` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
-> UNIQUE KEY `clothes` (`hat`,`mittens`)
-> ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
Query OK, 0 rows affected (0.01 sec)
mysql> INSERT INTO tbl (hat,mittens,name) VALUES ('blue','green','george');
Query OK, 1 row affected (0.00 sec)
mysql> select * from tbl;
+------+---------+--------+---------------------+
| hat | mittens | name | stamp |
+------+---------+--------+---------------------+
| blue | green | george | 2009-06-27 12:15:16 |
+------+---------+--------+---------------------+
1 row in set (0.00 sec)
mysql> INSERT INTO tbl (hat,mittens,name) VALUES ('blue','green','george') ON DUPLICATE KEY UPDATE name='george';
Query OK, 2 rows affected (0.00 sec)
mysql> select * from tbl;
+------+---------+--------+---------------------+
| hat | mittens | name | stamp |
+------+---------+--------+---------------------+
| blue | green | george | 2009-06-27 12:15:30 |
+------+---------+--------+---------------------+
1 row in set (0.00 sec)
mysql> INSERT INTO tbl (hat, mittens, name) VALUES ('blue','green','george') ON DUPLICATE KEY UPDATE name=CASE WHEN name <> VALUES(name) THEN VALUES(name) ELSE name END;
Query OK, 2 rows affected (0.00 sec)
mysql> select * from tbl;
+------+---------+--------+---------------------+
| hat | mittens | name | stamp |
+------+---------+--------+---------------------+
| blue | green | george | 2009-06-27 12:15:42 |
+------+---------+--------+---------------------+
1 row in set (0.00 sec)
mysql> INSERT INTO tbl (hat,mittens,name) VALUES ('blue','green','george') ON DUPLICATE KEY UPDATE name = CASE WHEN name <> VALUES(name) THEN VALUES(name) ELSE name END, stamp = CASE WHEN name <> VALUES(name) THEN now() ELSE stamp END;
Query OK, 2 rows affected (0.00 sec)
mysql> select * from tbl;
+------+---------+--------+---------------------+
| hat | mittens | name | stamp |
+------+---------+--------+---------------------+
| blue | green | george | 2009-06-27 12:15:42 |
+------+---------+--------+---------------------+
1 row in set (0.00 sec)
mysql>
Hãy cho tôi biết nếu bạn có bất kỳ câu hỏi nào.
HTH,
-Dipin