Как вставить запись или обновить, если она уже существует?

у меня есть таблица со столбцами record_id (auto inc),sender, sent_time и status.

в случае, если нет никакой записи конкретного отправителя, например "sender1", я должен вставить новую запись, иначе я должен обновить существующую запись, которая принадлежит "user1".

поэтому, если нет никакой записи, уже сохраненной, я бы выполнил

# record_id is AUTO_INCREMENT field
INSERT INTO messages (sender, sent_time, status)
VALUES (@sender, time, @status)

иначе бы исполнить заявление.

в любом случае.. кто-нибудь знает, как совместить эти два оператора для вставки новой записи, если нет никакой записи, где значение отправителя поля "user1" в противном случае обновляет существующую запись?

6 ответов


MySQL поддерживает вставка-на-дубликат синтаксис, Ф.е.:

INSERT INTO table (key,col1) VALUES (1,2)
  ON DUPLICATE KEY UPDATE col1 = 2;

если у вас есть твердые ограничения на таблице, то вы также можете использовать REPLACE INTO для этого. Вот цитата из MySQL:

REPLACE работает точно так же, как INSERT, за исключением того, что если старая строка в таблице имеет то же значение, что и новая строка для первичного ключа или уникального индекса, старая строка удаляется до вставки новой строки.

синтаксис в основном такой же, как INSERT INTO, просто заменить INSERT by REPLACE.

INSERT INTO messages (sender, sent_time, status) VALUES (@sender, time, @status)

то будет

REPLACE INTO messages (sender, sent_time, status) VALUES (@sender, time, @status)

обратите внимание, что это специфичная для MySQL команда, которая не встречается в других БД, поэтому имейте в виду переносимость.


Как упоминали другие, вы должны использовать " insert...при дублировании обновления ключа", иногда называемый "upsert". Однако, в вашем конкретном случае вы не хотите использовать статическое значение в обновлении, а, скорее, значение, которое вы передаете в предложении values инструкции Insert.

в частности, я думаю, что вы хотите обновить два столбца, если строка уже существует:

1) sent_time
2) status

чтобы сделать это, вы должны использовать оператор "upsert", как это (используя пример):

INSERT INTO messages (sender, sent_time, status) 
VALUES (@sender, time, @status)
ON DUPLICATE KEY UPDATE 
  sent_time = values(sent_time),
  status = values(status);

проверить "вставить на дубликат ключа обновление".

INSERT INTO table (a,b,c) VALUES (1,2,3)
  ON DUPLICATE KEY UPDATE c=c+1;

UPDATE table SET c=c+1 WHERE a=1;

один из параметров используется для синтаксиса повторяющегося обновления

http://dev.mysql.com/doc/refman/5.1/en/insert-on-duplicate.html

другие параметры делают выбор, чтобы выяснить, существует ли запись, а затем doind inser/update соответственно. Имейте в виду, что если вы withing transaction select не будет явно завершать транзакцию, поэтому безопасно ее использовать.


use merge statement :

merge into T1
          using T2
          on (T1.ID = T2.ID)
    when  matched
    then  update set  
                      T1.Name = T2.Name
    when  not matched
    then  insert values (T2.ID,T2.Name);