Подтвердить что ты не робот

INSERT... НА ОБНОВЛЕНИИ КЛЮЧА DUPLICATE с ГДЕ?

Я делаю INSERT ... ON DUPLICATE KEY UPDATE, но мне нужно, чтобы часть обновления была условной, и только обновление, если какое-то дополнительное условие изменилось.

Однако WHERE не допускается на этом UPDATE. Есть ли обходной путь для этого?

Я не могу делать комбинации INSERT/UPDATE/SELECT, так как это необходимо для работы над репликацией.

4b9b3361

Ответ 1

Я предлагаю вам использовать IF() для этого.

См.: условный-дубликат-ключ-обновления-с-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);

Ответ 2

Это наше окончательное решение, работает как шарм!

Игнорирование вставки гарантирует, что строка существует как на главном, так и на ведомом устройстве, в случае, если они когда-либо были перенаправлены.

Обновление... где гарантирует, что только самое последнее обновление в глобальном масштабе является конечным результатом после выполнения всей репликации.

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();

Ответ 3

вы можете использовать два оператора вставки: поскольку вы можете добавить предложение where к части выбора для исходных данных.

выберите два набора данных, один из которых вы будете вставлять с символом "on duplicate", а другой будет вставлен без дубликата.

Ответ 4

table php_lock:
name: idString, locked: bool, time: метка времени, locked_by: строка и значения для вставки или update
1, CURRENT_TIMESTAMP, 'script' где name= 'wwww' AND locked= 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`);

Ответ 5

обзор

  • AWUpsertCondy хочет изменить ПЕРЕД на ПОСЛЕ

SimplifiedProblemIllustration

проблема

  • AWUpsertCondy не хочет, чтобы запрос вставки не выполнялся, если MySQL обнаруживает повторяющийся первичный ключ
  • MySQL не поддерживает условное предложение WHERE с ON DUPLICATE KEY UPDATE

Решение

  • MySQL поддерживает условное предложение с помощью функции IF()
  • Здесь у нас есть простое условное обновление только тех элементов с идентификатором пользователя менее 9
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 )
;

Ловушки

  • Мы вводим переменную MySQL @doupdate, чтобы указать, соответствует ли строка UPDATE условию. Затем мы используем эту же переменную для всех столбцов базы данных, которые мы используем в инструкции UPDATE.
  • В первом условном выражении мы оба объявляем переменную и определяем, применимо ли условное условие. Этот подход, возможно, более громоздкий, чем предложение WHERE

Смотрите также

Ответ 6

On duplicate key не позволяют нам использовать предложение where, поэтому есть две альтернативы для достижения того же.

  • Если вы знаете, что большую часть времени вы получите дубликат, тогда

    a. Update the table first using update query and where clause b. If update fails then insert the record into table using insert query

  • Если вы знаете, что большую часть времени вы собираетесь вставлять в таблицу,

    a. Insert the record into table using insert ignore query - what it does is actually ignore the insert if duplicate key found b. If insert ignore fails then update the record using update query

Для справки insert ignore нажмите здесь