sql >> Database teknologi >  >> RDS >> Mysql

betinget af dobbeltnøgleopdatering

Du kan bruge normale sql-konstruktioner i ON DUPLICATE KEY syntaks. Så for at lave betingede opdateringer under en indsættelse kan du gøre følgende:

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;

Dette vil ændre værdien til det, du har angivet til insert-sætningen, når den er forskellig fra den, der er i rækken, og vil indstille værdien til at være, hvad den allerede er, hvis den ikke er ændret, og vil resultere i, at MySQL ikke gør noget for at bevare rækken last_update tidsstemplet som Quassnoi påpegede.

Hvis du ville være 100 % sikker på, at du ikke stolede på adfærden i MySQL, hvor den ikke opdaterer en række, hvis du angiver en værdi til sig selv, kan du gøre følgende for at tvinge tidsstemplet:

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;

Dette vil kun opdatere last_update til now() når navnet er ændret ellers vil det fortælle MySQL at beholde værdien af ​​last_update .

I sektionen ON DUPLICATE KEY i erklæringen kan du også henvise til kolonnerne i tabellen ved deres navn, og du kan få de værdier, du har angivet til sektionen Indsæt sætningsværdier ved hjælp af VÆRDIER(kolonne_navn) funktion.

Det følgende er en log, der viser, at den sidst leverede sætning fungerer selv på 4.1, hvor de andre ikke virker på grund af en fejl, der blev rettet i version 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>

Sig til, hvis du har spørgsmål.

HTH,

-Dipin



  1. Hvordan flytter jeg min eksisterende rails-app til heroku? (sqlite til postgres)

  2. kryds anvende xml-forespørgsel klarer sig eksponentielt dårligere, efterhånden som xml-dokumentet vokser

  3. Tæl antallet af rækker i golang

  4. SqlBulkCopy fra en liste<>