在mysql中防止十进制值变为负数

时间:2017-07-14 14:10:06

标签: php mysql

防止用户的平衡变为负面 (除了PHP方面的检查)我使用了以下BEFORE INSERT Mysql Trigger:

BEGIN

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

    -- Some other inserts etc...

END

我认为这是一个BEFORE INSERT触发器,它会阻止插入任何可能使余额为负数的新发票,但它不会。

即使STRICT MODE为ON且user_balance列为UNSIGED DECIMAL,触发器也不会停止插入,如果字段为负,则字段简单地变为0 ...

我尝试手动运行UPDATE查询,但是它会按预期抛出错误,触发器的行为也不一样。

编辑:

  

有没有人知道为什么它在手册UPDATE上工作正常,但没有触发?

1 个答案:

答案 0 :(得分:1)

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

 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;