Ответ 1
Вы можете использовать обычные sql-конструкции в синтаксисе ON DUPLICATE KEY. Поэтому для выполнения условных обновлений во время вставки вы можете сделать следующее:
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;
Это изменит значение на то, что вы указали в инструкции insert, когда оно отличается от того, что в строке, и установит значение как то, что уже есть, если оно не изменилось и приведет к тому, что MySQL ничего не сделает строка, сохраняющая временную метку last_update, как указал Квасной.
Если вы хотите сделать 100% уверенным, что вы не полагаетесь на поведение MySQL, где он не обновляет строку, если вы установите значение для себя, вы можете сделать следующее, чтобы заставить отметку времени:
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;
Это обновит только last_update
до now()
, когда имя изменилось иначе, это покажет, что MySQL сохранит значение last_update
.
Кроме того, в разделе ON DUPLICATE KEY этого оператора вы можете ссылаться на столбцы в таблице по их имени, и вы можете получить значения, предоставленные в разделе значений операторов вставки, используя VALUES (column_name).
Ниже приведен журнал, который показывает, что последний предоставленный оператор работает даже на 4.1, где остальные не работают из-за ошибки, которая была исправлена в версии 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>
Сообщите мне, если у вас есть какие-либо вопросы.
НТН,
-Dipin