MySQL触发器不能在UPDATE语句中使用相同的表

时间:2013-08-10 17:31:36

标签: mysql triggers

所以基本上我试图创建一个触发器,通过增加俯卧撑,上拉和3英里跑的分数来更新我的300挑战表中的分数。 3英里跑的得分在下面的SELECT大。

create trigger update_wscore
AFTER INSERT
ON 300challenge FOR EACH ROW

Create table temp(3mile_score integer);
insert into temp(3mile_score) 
select 
  case 
    WHEN TIMEDIFF (3mile , '00:18:00') > '00:00:10' 
      THEN
         CASE 
            WHEN
              100 - (EXTRACT(MINUTE FROM TIMEDIFF (3mile, '00:18:00')) * 6 +
              FLOOR(EXTRACT(SECOND FROM TIMEDIFF (3mile, '00:18:00')) / 10)) < 0
            THEN 0
         ELSE 
              100 - (EXTRACT(MINUTE FROM TIMEDIFF (3mile, '00:18:00')) * 6 +
              FLOOR(EXTRACT(SECOND FROM TIMEDIFF (3mile, '00:18:00')) / 10))
         END
  ELSE 100
END
FROM 300challenge
WHERE wscore IS NULL;

UPDATE 300challenge
SET wscore = pushups * 2 + pullups * 5 + (select * from temp);

drop table temp;

我已尝试直接在SELECT语句中使用UPDATE wscore替换select * fom temp,但它无法说明我无法使用300challenge表格SELECT FROM语句中的UPDATE子句。

之后我尝试了上面显示的内容,创建了一个临时表,我在其中转储得分并读取它以便在UPDATE中使用。

但显然这种方法不足以欺骗系统,因为它现在抛出了一个错误Explicit or implicit commit is not allowed in stored function or trigger.

我有点想法,所以如果有人能给出一些建议,他们会非常欢迎。

更新

我现在也尝试从触发器移除CREATE TABLE TEMP,在触发器外创建表(一次)并用drop table temp替换触发器的最后一行truncate table temp,但显然我的webhost不允许触发器 TRIGGER command denied to user '--'@'localhost' for table '300challenge'

我的代码现在是

CREATE TABLE TEMP (3mile_score INT);

CREATE TRIGGER update_wscore
AFTER INSERT ON 300 challenge
FOR EACH ROW

INSERT INTO TEMP (3mile_score)
SELECT CASE 
    WHEN TIMEDIFF(3mile, '00:18:00') > '00:00:10'
      THEN CASE 
          WHEN 100 - (EXTRACT(MINUTE FROM TIMEDIFF(3mile, '00:18:00')) * 6 +
               FLOOR(EXTRACT(SECOND FROM TIMEDIFF(3mile, '00:18:00')) / 10)) < 0
            THEN 0
          ELSE 100 - (EXTRACT(MINUTE FROM TIMEDIFF(3mile, '00:18:00')) * 6 +
               FLOOR(EXTRACT(SECOND FROM TIMEDIFF(3mile, '00:18:00')) / 10))
          END
    ELSE 100
    END
FROM 300 challenge
WHERE wscore IS NULL;

UPDATE 300 challenge
SET wscore = pushups * 2 + pullups * 5 + (
    SELECT *
    FROM TEMP
    );

TRUNCATE TABLE TEMP;

2 个答案:

答案 0 :(得分:1)

尝试将其重新定义为before insert触发器并修改new记录中的值。

触发器的内部将是这样的:

SET new.wscore = old.pushups * 2 + old.pullups * 5 +
    case 
    WHEN TIMEDIFF (old.3mile , '00:18:00') > '00:00:10' 
      THEN
         CASE 
            WHEN
              100 - (EXTRACT(MINUTE FROM TIMEDIFF (old.3mile, '00:18:00')) * 6 +
              FLOOR(EXTRACT(SECOND FROM TIMEDIFF (old.3mile, '00:18:00')) / 10)) < 0
            THEN 0
         ELSE 
              100 - (EXTRACT(MINUTE FROM TIMEDIFF (old.3mile, '00:18:00')) * 6 +
              FLOOR(EXTRACT(SECOND FROM TIMEDIFF (old.3mile, '00:18:00')) / 10))
         END
  ELSE 100
END;

答案 1 :(得分:0)

所以,我已经设法为此找到了一个解决方法,如果有人有耐心阅读整个问题,如果不是,我会在这里简要总结一下我的结论。

即使我设法克服了错误,即无法在SELECT语句中使用相同的表并使用UPDATE语句中的值,如

UPDATE table
SET col1 = (select max(col1) from table)

使用临时表。在为我的第二个CODE帖子创建了正确的代码之后,在我更新的问题部分中,我仍然无法使其工作,因为WEBHOST不允许创建触发器。

现在,作为解决方法,我在我的应用程序中创建了一个新网页,在INSERTING数据进入表格后,我立即使用触发器中使用的确切代码更新了我需要的列({ {1}},INSERTUPDATE)。我实际上将触发器的功能从数据层移动到了我的应用程序的业务层。

我希望这可以帮助受其网站主机限制并且无法使用其数据层的全部功能的任何其他人。