Mysql не обновлять, если строка не существует - PullRequest
1 голос
/ 15 марта 2019

Я создал веб-приложение, которое позволяет отправлять деньги другим людям (например, PayPal) для проекта университета.

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

Система работает с этими запросами:

         SET @moneytosend= ? ; //amount to send
         START TRANSACTION;
         UPDATE users SET balance= balance- @moneytosend WHERE id = ?; //sender's ID
         UPDATE users SET balance= balance+ @moneytosend WHERE id = ?; //receiver's ID
         COMMIT WORK;

Проблема заключается в том, что пользователь вставляет несуществующий идентификатор, и запрос все еще выполняется, эффективно удаляя деньги из отправителя.

Извините, если мой английский не идеален, и еще раз извините, если есть какие-либо ошибки форматирования.

Ответы [ 2 ]

1 голос
/ 15 марта 2019

Проблема вызвана 1-м оператором обновления и может быть решена путем добавления EXISTS в качестве условия:

update users
set balance = balance - @moneytosend
where 
  balance >= @moneytosend 
  and
  id = ? <-- sender id
  and 
  exists (
    select 1 from (select * from users where id = ? <-- receiver id
  ) t);

См. Демонстрационную версию По предложению Рэймонда Нейланда, сделайте дополнительную проверку, чтобы баланс не получил отрицательное значение.

1 голос
/ 15 марта 2019

Один из способов - проверить, существуют ли пользователи в запросах update:

UPDATE users JOIN
       (SELECT ? as sender_id, ? as receiver_id
       ) uu
       ON u.id IN (uu.sender_id, uu.receiver_id)
    SET balance = balance + (CASE WHEN u.id = uu.receiver_id THEN @moneytosend ELSE - @moneytosend)
    WHERE EXISTS (SELECT 1 FROM users u2 WHERE u2.id = uu.sender_id) AND
          EXISTS (SELECT 1 FROM users u2 WHERE u2.id = uu.receiver_id);

Эта логика объединяет запросы в один запрос и позволяет вводить только два параметра.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...