Mysql
 sql >> Datenbank >  >> RDS >> Mysql

abhängig von doppelter Schlüsselaktualisierung

Sie können normale SQL-Konstrukte im ON DUPLICATE KEY verwenden Syntax. Um also während einer Einfügung bedingte Aktualisierungen durchzuführen, können Sie Folgendes tun:

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;

Dies ändert den Wert in den Wert, den Sie der Insert-Anweisung gegeben haben, wenn er sich von dem in der Zeile unterscheidet, und setzt den Wert auf den Wert, den er bereits hat, wenn er sich nicht geändert hat, und führt dazu, dass MySQL nichts an der Beibehaltung der Zeile unternimmt der last_update-Zeitstempel, wie Quassnoi darauf hingewiesen hat.

Wenn Sie 100 % sichergehen möchten, dass Sie sich nicht auf das Verhalten von MySQL verlassen, wo es eine Zeile nicht aktualisiert, wenn Sie einen Wert auf sich selbst setzen, können Sie Folgendes tun, um den Zeitstempel zu erzwingen:

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;

Dadurch wird nur last_update aktualisiert zu now() Wenn sich der Name geändert hat, wird MySQL sonst angewiesen, den Wert von last_update beizubehalten .

Außerdem können Sie im ON DUPLICATE KEY-Abschnitt der Anweisung auf die Spalten in der Tabelle anhand ihres Namens verweisen und die Werte abrufen, die Sie im Werteabschnitt der Insert-Anweisung angegeben haben, indem Sie VALUES(column_name) Funktion.

Das Folgende ist ein Protokoll, das zeigt, dass die letzte bereitgestellte Anweisung sogar unter 4.1 funktioniert, wo die anderen aufgrund eines Fehlers, der in Version 5.0 behoben wurde, nicht funktionieren.

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>

Lassen Sie mich wissen, wenn Sie Fragen haben.

HTH,

-Dipin