risentveber
@risentveber
fullstack web developer

Как пофиксить SQL запрос?

Данный код после подстановки параметров :player_id, :mob_id, :count
do $$
begin
  IF EXISTS (SELECT * FROM player_mob_kills WHERE player_id= :player_id and mob_id= :mob_id) THEN
      UPDATE player_mob_kills SET count = count + :count WHERE player_id= :player_id and mob_id= :mob_id;
  ELSE
      INSERT INTO player_mob_kills (player_id, mob_id, count) VALUES  (:player_id, :mob_id, :count);
  END IF;
end
$$;

иногда падает с ошибкой
SQLSTATE[23505]: Unique violation: 7 ERROR:  duplicate key value violates unique constraint \"player_mob_kills_player_id_mob_id_unique\"\nDETAIL: 
 Key (player_id, mob_id)=(54298, 23) already exists.
  • Вопрос задан
  • 349 просмотров
Решения вопроса 1
qonand
@qonand
Software Engineer
ошибка возникает в следствии попытки добавить данные с одинаковыми Primary Key. Используйте UPSERT если это позволяет Ваша версия постгреса, если не позволяет - в интернете полной информации как реализовать самому его аналог в более старых версиях.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
Может так?
INSERT IGNORE INTO player_mob_kills
Судя по всему ошибка возникает когда игрок уже убивал этого моба. Тогда правильнеебудет добавить столбец с количеством и проверка есть ли такая пара игрок-моб, если есть то счётчик ++
INSERT IGNORE для вашего случая не думаю что подходит судя по контексту запроса...
Ответ написан
@bizon2000
Java-программист
Можно сделать условное добавление строки с нулевым счетчиком и потом выполнить обновление строки для изменения счетчика:
INSERT INTO player_mob_kills (player_id, mob_id, count)
    SELECT :player_id, :mob_id, 0
        WHERE NOT EXISTS(SELECT *
                             FROM player_mob_kills
                             WHERE player_id = :player_id
                               AND mob_id = :mob_id
                        )
UPDATE player_mob_kills
    SET count=count + :count
    WHERE player_id = :player_id
      AND mob_id = :mob_id;
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы