更新触发后如何避免MySQL错误1442?

更新触发后如何避免MySQL错误1442?,mysql,sql,Mysql,Sql,我必须用MySQL而不是PHP构建一个简单的推荐系统。 当用户获得积分时,其推荐人也必须自动获得该积分的10%,以此类推,当积分大于1时。 例子: 吉姆挣20英镑, 他的推荐人约翰赚了2英镑, 所以他的推荐人分数没有赚到,因为他的分数是0.2 代码如下: drop table if exists account; create table test.account( username char(100) PRIMARY KEY, points int, referrer char(100) )E

我必须用MySQL而不是PHP构建一个简单的推荐系统。 当用户获得积分时,其推荐人也必须自动获得该积分的10%,以此类推,当积分大于1时。 例子: 吉姆挣20英镑, 他的推荐人约翰赚了2英镑, 所以他的推荐人分数没有赚到,因为他的分数是0.2

代码如下:

drop table if exists account;
create table test.account(
username char(100) PRIMARY KEY,
points int,
referrer char(100)
)ENGINE = InnoDB DEFAULT CHARACTER SET = latin1 COLLATE = latin1_general_cs;

drop trigger if exists updater;
DELIMITER //
CREATE TRIGGER updater AFTER UPDATE ON account FOR EACH ROW
BEGIN
SET @points_to_referrer=(NEW.points-OLD.points)*0.1;
IF(@points_to_referrer>1)THEN
    UPDATE account SET points=points+@points_to_referrer WHERE username=OLD.referrer;
END IF;
END //
DELIMITER ;

INSERT INTO `test`.`account` (`username`, `points`, `referrer`) VALUES ('john', '10', 'mark');
INSERT INTO `test`.`account` (`username`, `points`, `referrer`) VALUES ('mark', '10', 'jim');
INSERT INTO `test`.`account` (`username`, `points`, `referrer`) VALUES ('jim', '10', 'john');
…这是一个comand示例:

UPDATE `test`.`account` SET `points`='30' WHERE `username`='jim';
此命令触发1442错误而不是更新,因为它似乎是一个无限循环。 我可以通过设置任何系统选项(可能在my.ini中)强制执行此代码吗? 还是有其他方法可以解决这个问题?谢谢。

您无法更新调用触发器的表(帐户):

在存储的函数或触发器中,不允许修改 已被用户(用于读或写)使用的表 调用函数或触发器的语句

这样做将生成错误1442:

Error Code: 1442
Can't update table 'account' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.

解决方案:如果您只想在更新前设置字段的值,可以在触发器上使用更新前的
并使用
新建
运算符:

DROP TRIGGER IF EXISTS updater;
DELIMITER //
CREATE TRIGGER updater BEFORE UPDATE ON account FOR EACH ROW
BEGIN
    SET @points_to_referrer=(NEW.points-OLD.points)*0.1;
    IF(@points_to_referrer > 1)THEN
        SET NEW.points = NEW.points + @points_to_referrer;
    END IF;
END //
DELIMITER ;

由于尚未更新/插入字段值,您可以在更新/插入之前使用
设置字段值。您需要做的就是将
NEW.
(当前行的所有值都可以使用
NEW.
)设置为您想要的任何值。

您最好使用更新前触发器。与之前的错误相同。我猜您不能对更新触发器使用更新,但可以使用其他表和事件(从未使用过)对于
创建表ref_收益(username char(10)主键,points int,给定tinyint)ENGINE=InnoDB并且您可以在更新触发器时插入到该表中。