在同一 table 上使用触发器插入新行
Inserting new row using a trigger on same table
我有一个tableJOB
。它有以下列:cycle_id, job_id, status
.
每个周期执行7个作业。所以cycle_id
和job_id
形成复合主键。
status 列可以具有以下值:WAITING_TO_START, RUNNING. COMPLETED
。
每个作业都是一个 cron 作业。每项工作由不同的人负责,所以为了同步每个人,我正在使用数据库 table JOB。每个工作都听 JOB table 并观察它是否有一行 job_id 和状态为 'WAITING_TO_START'。因此,每当作业状态更改为已完成时,我想要的是,下一个作业行是用 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 table 执行更新时,出现以下错误:
UPDATE job SET status='COMPLETED' WHERE cycle_id=1 AND job_id=1;
ERROR 1442 (HY000): Can't update table 'job' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
那么有没有办法实现同步呢。我不希望每个作业都创建一个包含下一个作业 ID 的行。我希望它自动处理。这个触发器可以用不同的方式编写还是应该使用其他机制。
您将无法 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;
虽然该过程需要对您的代码进行一些修改(即您需要调用该过程而不是直接更新数据),但该过程的好处更加明显 - 触发器可以在后台自动执行操作不直观。
我有一个tableJOB
。它有以下列:cycle_id, job_id, status
.
每个周期执行7个作业。所以cycle_id
和job_id
形成复合主键。
status 列可以具有以下值:WAITING_TO_START, RUNNING. COMPLETED
。
每个作业都是一个 cron 作业。每项工作由不同的人负责,所以为了同步每个人,我正在使用数据库 table JOB。每个工作都听 JOB table 并观察它是否有一行 job_id 和状态为 'WAITING_TO_START'。因此,每当作业状态更改为已完成时,我想要的是,下一个作业行是用 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 table 执行更新时,出现以下错误:
UPDATE job SET status='COMPLETED' WHERE cycle_id=1 AND job_id=1;
ERROR 1442 (HY000): Can't update table 'job' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
那么有没有办法实现同步呢。我不希望每个作业都创建一个包含下一个作业 ID 的行。我希望它自动处理。这个触发器可以用不同的方式编写还是应该使用其他机制。
您将无法 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;
虽然该过程需要对您的代码进行一些修改(即您需要调用该过程而不是直接更新数据),但该过程的好处更加明显 - 触发器可以在后台自动执行操作不直观。