插入多行而不是一行的触发器

时间:2016-02-04 21:31:01

标签: sql oracle triggers

我们遇到以下触发器问题。当没有新UPDATEPROCESSINFO的行时,我们想在INSTANCEID表中插入一行,并为下一个更新它。

但我们惊讶地发现有时候我们有多行具有相同的INSTANCEID。是因为它非常快吗?如何防止这种情况发生?我们的目标是每INSTANCEID行一行。

感谢您的帮助

create or replace TRIGGER TRIG_UPDATE_PROCESS_INFO
  AFTER INSERT ON PROCESSSTEP
  FOR EACH ROW
DECLARE
  AUDIT_TIME TIMESTAMP(6);
BEGIN
  SELECT MAX(LASTUPDATETIME)
    INTO AUDIT_TIME
    FROM UPDATEPROCESSINFO
    WHERE INSTANCEID = :NEW.INSTANCEID;

  IF AUDIT_TIME IS NULL THEN
    INSERT INTO UPDATEPROCESSINFO
      (INSTANCEID, STEPID, STEPSTATUS, STEPITERATION, LASTUPDATETIME)
    VALUES
      (:NEW.INSTANCEID, :NEW.STEPID, :NEW.STATUS, :NEW.STEPITERATION, :NEW.AUDITTIMESTAMP);
  ELSIF :NEW.AUDITTIMESTAMP > AUDIT_TIME THEN
    UPDATE UPDATEPROCESSINFO
      SET STEPID = :NEW.STEPID,
          LASTUPDATETIME = :NEW.AUDITTIMESTAMP,
          STEPSTATUS = :NEW.STATUS,
          STEPITERATION = :NEW.STEPITERATION
      WHERE INSTANCEID = :NEW.INSTANCEID;
  END IF;
END;

1 个答案:

答案 0 :(得分:1)

这可能正在发生,因为您有多个会话插入到PROCESSSTEP中以获得相同的INSTANCEID。如果两个会话几乎同时插入PROCESSSTEP,并且他们都没有提交他们的更改,那么两个会话都不会"看到"其他的更改,都会认为UPDATEPROCESSINFO中不存在一行。

在我看来,这个设计似乎有问题。我建议将其更改为具有PROCESS_STEP_HISTORY表,并且在完成该过程中的每个步骤时,将一行插入到PROCESS_STEP_HISTORY中以记录已完成的过程步骤的信息。然后,当需要找到关于" last"的信息时已完成的步骤,它将执行类似

的操作
SELECT a.*
  FROM (SELECT *
          FROM PROCESS_STEP_HISTORY h
          WHERE INSTANCE_ID = whatever
          ORDER BY LASTUPDATETIME DESC) a
  WHERE ROWNUM = 1

它还具有保留过程中每个步骤的信息的优点,这可能证明是有用的。

我也不建议使用触发器来做这类事情。这是业务逻辑,将业务逻辑放入触发器永远不是一个好主意。

祝你好运。