防止用户的平衡变为负数
(除了PHP端的检查之外)我使用了以下Mysql触发器:

BEGIN

    UPDATE `table` SET `user_balance` = user_balance - NEW.amount WHERE `uid` = NEW.id;

    -- Some other inserts etc...

END

我想,由于这是一个BEFORE INSERT触发器,它将阻止插入任何可能使余额为负的新发票,但它没有。
即使“严格”模式处于打开状态,BEFORE INSERT列为user_balance,触发器也不会停止插入,如果该字段为负,则将其简单地转换为0。。。
我试着手动运行一个更新查询,但是它像预期的那样抛出了一个错误,触发器的动作不一样。
编辑:
有人知道为什么它在手动操作时可以正常工作,但在使用触发器时不行吗?

最佳答案

在执行更新之前,必须检查减法的结果。

 UPDATE `table`
 SET `user_balance` = user_balance - NEW.amount
 WHERE `uid` = NEW.id
   AND user_balance - NEW.amount >= 0

或者最好先获取值并引发错误:
Throw an error in a MySQL trigger
 SET @user_balance := 0;
 SELECT @user_balance := `user_balance`
 FROM `table`
 WHERE `uid` = NEW.id;

IF @user_balance - user_balance >= 0 THEN
     UPDATE `table`
     SET `user_balance` = user_balance - NEW.amount
     WHERE `uid` = NEW.id
       AND user_balance - NEW.amount >= 0
ELSE
    set @msg = concat('MyTriggerError: Trying to insert a negative value in trigger: '
                     , cast(@user_balance - NEW.amount as varchar));
    signal sqlstate '45000' set message_text = @msg;
END IF;

10-07 17:43