在同一个表上使用触发器插入新行

时间:2015-05-31 09:44:02

标签: mysql database-trigger

我有一张桌子JOB。它有以下列:cycle_id, job_id, status

每个周期都有7个作业。因此cycle_idjob_id形成复合主键。

状态列可以包含以下值:WAITING_TO_START, RUNNING. COMPLETED

每份工作都是一份工作。并且每个工作都是不同的人的责任,所以要同步每个人我正在使用数据库表JOB。每个作业都会监听JOB表并观察它是否有一行,其job_id和状态为“WAITING_TO_START”。因此,无论何时将作业状态更改为COMPLETED,都会创建下一个作业行,cycle_id与更新作业相同,job_id作为更新作业的ID + 1,状态为“WAITING_TO_START”。所以我为此创建了一个触发器:

DELIMITER $$

CREATE TRIGGER start_new_job
AFTER UPDATE ON job
FOR EACH ROW
BEGIN
IF NEW.status = 'COMPLETED' AND OLD.job_id <=6 THEN
   INSERT INTO job(cycle_id, job_id, status) VALUES (OLD.cycle_id, OLD.job_id+1, 'WATING_TO_START');
END IF;
END$$
DELIMITER ;

但是当我在JOB表上执行更新时,我收到以下错误:

UPDATE job SET status='COMPLETED' WHERE cycle_id=1 AND job_id=1;
  

ERROR 1442(HY000):无法更新存储函数/触发器中的表'job',因为它已被调用此存储函数/触发器的语句使用。

有没有办法实现同步。我不希望每个作业都创建一个包含下一个作业ID的行。我想让它自动处理。这个触发器可以用不同的方式编写,还是应该使用其他机制。

1 个答案:

答案 0 :(得分:1)

您将无法insert into the same table from a trigger。我将使用过程替换您的触发器,然后通过以下过程引导所有状态更新:

CREATE PROCEDURE UpdateJobStatus(jobId INT, NewStatus NVARCHAR(50))
BEGIN
  UPDATE job
     SET `Status` = NewStatus 
     WHERE job_id = jobId;

  IF NewStatus = 'COMPLETED' AND jobId <=6 THEN
    INSERT INTO job(cycle_id, job_id, status) 
       SELECT cycle_id, job_id+1, 'WATING_TO_START'
       FROM job 
       WHERE job_id = jobId;
  END IF;
END;

Sql Fiddle here

虽然该过程需要对您的代码进行一些修改(即您需要调用该过程而不是直接更新数据),但该过程具有更明显的好处 - 触发器在后台自动执行操作可能是非,直观。