<rmcreative>

RSS

MySQL: добавить если ещё нет

19 декабря 2008

Иногда требуется вставить запись в таблицу, если её там до сих пор нет. Можно сделать пару запросов: одним —проверить, другим — вставить, а можно и одним:

INSERT IGNORE INTO `users`
SET `login` = 'samdark', `password` = 'mypassword';

Поле login должно быть уникальным.

Комментарии RSS

  1. №982
    Andrey
    Andrey 19.12.2008, 15:17:51

    Похожая задача - если нужно вставить, а если уже есть - изменить.

    INSERT INTO users(login, password) VALUES('login', 'password') ON DUPLICATE KEY UPDATE password='password';

  2. №983
    Shadow
    Shadow 19.12.2008, 16:24:24

    Andrey, а почему не replace?

    REPLACE INTO users (`login`, `password`) VALUES('login', 'password');
  3. №984
    Andrey
    Andrey 19.12.2008, 16:28:22

    Shadow, честно говоря ни разу не пользовался, но подозреваю, что здесь есть разница. Например, если у нас есть таблица-счетчик, и нам нужно в случае первого посещения вставить запись, а в случае следующих - увеличить счетчик на единицу. Тогда пользуемся ON DUPLICATE KEY UPDATE counter=counter+1

  4. №985
    Sam
    Sam 19.12.2008, 16:29:16

    Shadow

    REPLACE будет перетирать существующие данные, не пропускать, как в случае с INSERT IGNORE.

  5. №986
    Sam
    Sam 19.12.2008, 16:37:17

    Оу… сорри, не заметил начала сообщения :)

  6. №987
    Андрей
    Андрей 19.12.2008, 16:38:25

    Sam, ну мы как бы не об аналоге говорим, а о похожих случаях. Никто не спорит, что оно не работает аналогично.

  7. №988
    Алексей Качаев
    Алексей Качаев 19.12.2008, 19:09:03

    ...Можно сделать пару запросов: одним —проверить, другим — вставить...

    Ни в коем случае так делать нельзя! Это грубая ошибка. Между первым запросом и вторым пройдет какое-то время. Вполне может оказать, что именно в этот промежуток другой процесс создаст записей, в отсутствии которой вы только что убедились.

  8. №989
    Dr.Death
    Dr.Death 19.12.2008, 19:16:20

    век живи век учись :)

  9. №990
    Андрей
    Андрей 19.12.2008, 20:21:11

    Алексей, в mysql, если я не ошибаюсь, есть транзакции. А до транзакций для этой цели существовала блокировка таблиц, которая работает и сейчас. То есть в самой проверке-вставке никакой грубой ошибки нет. Другое дело, что это повышает вероятность ошибки из-за того, что программист забудет вставить блокировку, или забудет вовремя разблокировать таблицу.

  10. №991
    Олег
    Олег 20.12.2008, 13:28:24

    Проверка и обновление в два запроса в одной транзакции зато гораздо более переносимое решение.

  11. №1499
    mihdan
    mihdan 14.04.2009, 11:12:21

    Век живи-век учись. Спасибо. Пригодилось

  12. №6503
    Rash
    Rash 30.07.2012, 14:20:15

    Отлично, спасибо за пример, очень пригодилось.

  13. №8127
    Сергей
    Сергей 04.07.2013, 11:53:42

    Уже не первый день с SQL, и вроде бы такой простой вопрос, а вот только что нашел решение. Большое спасибо!

  14. №9847
    Роман
    Роман 14.06.2015, 19:50:05

    А как быть, если во первых: поля не уникальны; во вторых - нужно смотреть по двум колонкам, если совпадают обе - не пишем, если одна - пишем ?

  15. №10619
    Владимир
    Владимир 12.08.2016, 14:16:06

    Спасибо, у меня получилось, пока не поставил нужное поле PRIMARY KEY или UNIQUE.

  1. Почта опубликована не будет.

  2. Можно использовать синтаксис Markdown или HTML.

  3. Введите ответ в поле. Щёлкните, чтобы получить другую задачу.