sql >> Database >  >> RDS >> Mysql

voorwaardelijk op dubbele sleutelupdate

U kunt normale sql-constructies gebruiken in de ON DUPLICATE KEY syntaxis. Dus om voorwaardelijke updates uit te voeren tijdens een insert kun je het volgende doen:

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;

Dit zal de waarde veranderen in wat je hebt opgegeven in de insert-instructie wanneer deze verschilt van wat er in de rij staat en zal de waarde instellen op wat het al is als het niet is veranderd en zal ertoe leiden dat MySQL niets doet aan het behoud van de rij de last_update tijdstempel zoals Quassnoi opmerkte.

Als u er 100% zeker van wilt zijn dat u niet vertrouwt op het gedrag van MySQL waar het geen rij bijwerkt als u een waarde op zichzelf instelt, kunt u het volgende doen om het tijdstempel te forceren:

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;

Hiermee wordt alleen de last_update . bijgewerkt naar now() wanneer de naam is veranderd, zal het MySQL vertellen om de waarde van last_update te behouden .

Ook kunt u in de sectie ON DUPLICATE KEY van de instructie naar de kolommen in de tabel verwijzen met hun naam en kunt u de waarden krijgen die u hebt opgegeven in de sectie 'insert statement values' met behulp van de WAARDEN(kolomnaam) functie.

Het volgende is een logboek dat laat zien dat de laatst verstrekte verklaring zelfs werkt op 4.1, terwijl de andere niet werken vanwege een bug die is opgelost in versie 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>

Laat het me weten als je vragen hebt.

HTH,

-Dipin



  1. Waarom evalueert NULL =NULL naar onwaar in de SQL-server?

  2. Hoe mysql-commando's vanaf terminal op een MAMP-installatie uit te voeren?

  3. Wat is de primaire sleutelbeperking in de SQL Server-database - SQL Server / T-SQL-zelfstudie, deel 54

  4. Hoe helpt databaseontwerp docenten, lessen en studenten te organiseren?