Je fais un INSERT ... ON DUPLICATE KEY UPDATE
mais j'ai besoin que la partie mise à jour soit conditionnelle, ne faisant la mise à jour que si une condition supplémentaire a changé.
Cependant, WHERE
n'est pas autorisé sur ce UPDATE
. Y a-t-il une solution à cela?
Je ne peux pas faire de combinaisons INSERT/UPDATE/SELECT car cela doit fonctionner sur une réplication.
Je vous suggère d'utiliser IF () pour ce faire.
Voir: conditionnel-duplicate-key-updates-with-mysql
INSERT INTO daily_events (created_on, last_event_id, last_event_created_at)
VALUES ('2010-01-19', 23, '2010-01-19 10:23:11')
ON DUPLICATE KEY UPDATE
last_event_id = IF(last_event_created_at < VALUES(last_event_created_at), VALUES(last_event_id), last_event_id);
Ceci est notre solution finale, fonctionne comme un charme!
insérer ignorer s'assurera que la ligne existe à la fois sur le maître et sur l'esclave, au cas où ils auraient déjà été détournés.
pdate ... where s'assure que seule la mise à jour la plus récente, au niveau mondial, est le résultat final après que toute la réplication soit effectuée.
mysql> desc test;
+-------+--------------+------+-----+-------------------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+-------------------+-------+
| id | int(11) | NO | PRI | NULL | |
| value | varchar(255) | YES | | NULL | |
| ts | timestamp | NO | | CURRENT_TIMESTAMP | |
+-------+--------------+------+-----+-------------------+-------+
mysql> insert ignore into test values (4, "foo", now());
mysql> update test set value = "foo", ts = now() where id = 4 and ts <= now();
vous pouvez utiliser deux instructions d'insertion .. puisque vous POUVEZ ajouter une clause where à la partie select pour les données source.
sélectionnez deux ensembles de données, l'un que vous insérerez avec "en double" et l'autre sera inséré sans "en double".
ON DUPLICATE KEY UPDATE
IF()
INSERT INTO zzdemo_table02
(lname,userid)
SELECT
lname,userid
FROM(
SELECT
lname,userid
FROM
zzdemo_table01
) as tt01
ON DUPLICATE KEY UPDATE
userid=IF(@doupdate:=IF( (tt01.userid < 9) , True, False),
tt01.userid, zzdemo_table02.userid)
,lname=IF(@doupdate, tt01.lname , zzdemo_table02.lname )
;
@doupdate
Afin d'indiquer si la ligne UPDATE remplit ou non la condition. Ensuite, nous utilisons cette même variable pour toutes les colonnes de base de données que nous utilisons dans l'instruction UPDATEtable
php_lock
:name
: idString,locked
: bool,time
: horodatage,locked_by
:chaîne
valeurs à insérer ou à mettre à jour
1, CURRENT_TIMESTAMP, 'script'
oùname
= 'wwww' ETlocked
= 2
INSERT INTO `php_lock` (`name`, locked, `time`, `locked_by`)
(SELECT * FROM
(SELECT `name`,1,CURRENT_TIMESTAMP, 'script' FROM `php_lock`
WHERE `name`='wwww' AND `locked`=2
UNION (
SELECT 'wwww',1 ,CURRENT_TIMESTAMP, 'script')
) AS temp LIMIT 1)
ON DUPLICATE KEY UPDATE locked=VALUES(locked), `time`=VALUES(`time`), `locked_by`=VALUES(`locked_by`);