SQLite INSERT - ON DUPLICATE KEY UPDATE (UPSERT) - PullRequest
88 голосов
/ 27 апреля 2010

MySQL имеет что-то вроде этого:

INSERT INTO visits (ip, hits)
VALUES ('127.0.0.1', 1)
ON DUPLICATE KEY UPDATE hits = hits + 1;

Насколько я знаю, эта функция не существует в SQLite, я хочу знать, есть ли способ достичь того же эффекта без необходимости выполнения двух запросов. Также, если это невозможно, что вы предпочитаете:

  1. SELECT + (ВСТАВИТЬ или ОБНОВИТЬ) или
  2. ОБНОВЛЕНИЕ (+ INSERT , если ОБНОВЛЕНИЕ не удается )

Ответы [ 5 ]

113 голосов
/ 27 апреля 2010
INSERT OR IGNORE INTO visits VALUES ($ip, 0);
UPDATE visits SET hits = hits + 1 WHERE ip LIKE $ip;

Для этого требуется, чтобы столбец «ip» имел ограничение UNIQUE (или PRIMARY KEY).


РЕДАКТИРОВАТЬ: еще одно отличное решение: https://stackoverflow.com/a/4330694/89771.

18 голосов
/ 27 апреля 2010

Я бы предпочел UPDATE (+ INSERT if UPDATE fails). Меньше кода = меньше ошибок.

11 голосов
/ 01 ноября 2018

Поскольку 3.24.0 SQLite также поддерживает upsert , теперь вы можете просто написать следующее

INSERT INTO visits (ip, hits)
VALUES ('127.0.0.1', 1)
ON CONFLICT(ip) DO UPDATE SET hits = hits + 1;
6 голосов
/ 17 ноября 2012

Текущий ответ будет работать только в sqlite ИЛИ mysql (в зависимости от того, используете вы ИЛИ или нет). Итак, если вы хотите кросс-совместимость с dbms, сделайте следующее ...

REPLACE INTO `visits` (ip, value) VALUES ($ip, 0);
0 голосов
/ 05 октября 2011

Вы должны использовать memcached для этого, так как это один ключ (IP-адрес), хранящий одно значение (количество посещений). Вы можете использовать функцию атомарного приращения, чтобы гарантировать отсутствие условий "гонки".

Это быстрее, чем MySQL, и экономит нагрузку, поэтому MySQL может сосредоточиться на других вещах.

...