1

私はテーブルを持っていますJOB。次の列がありますcycle_id, job_id, status

サイクルごとに実行されるジョブは 7 つあります。したがってcycle_idjob_id複合主キーを形成します。

status 列には次の値を指定できますWAITING_TO_START, RUNNING. COMPLETED

各ジョブは cron ジョブです。そして、各ジョブは別の人の責任であるため、各人を同期するために、データベーステーブル 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;

エラー 1442 (HY000): このストアド関数/トリガーを呼び出したステートメントで既に使用されているため、ストアド関数/トリガーのテーブル 'ジョブ' を更新できません。

同期を達成する方法はありますか。各ジョブが次のジョブの ID を持つ行を作成したくありません。自動で処理してほしい。このトリガーは別の方法で記述できますか、それとも他のメカニズムを使用する必要がありますか?

4

1 に答える 1

1

トリガーから同じテーブルに挿入することはできません。トリガーをプロシージャに置き換えてから、すべてのステータス更新をプロシージャに渡します。

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フィドルはこちら

プロシージャーはコードをいくらか変更する必要がありますが (つまり、データを直接更新するのではなく、プロシージャーを呼び出す必要があります)、プロシージャーにはより明白であるという利点があります。

于 2015-05-31T10:02:11.243 に答える