Postgres“插入或更新后”触发器未触发

时间:2020-06-09 15:15:32

标签: postgresql database-trigger

我已经将数据库从Oracle迁移到Postgres。步骤之一是保存记录的状态历史记录的副本。我通过在主表上执行INSERT,UPDATE触发器来完成此操作。触发器检查状态是否已更改,如果已更改,则将记录添加到状态历史记录表中。

CREATE OR REPLACE FUNCTION SAMPLE_STATUS_HISTORY_Trigger()
RETURNS TRIGGER AS $$
BEGIN
  IF( old.STATUS_CODE != new.STATUS_CODE ) THEN
    INSERT INTO SAMPLE_STATUS_HISTORY( analyte_status_history_id, sample_result_id, STATUS_CODE, status_date, status_user_id )
      VALUES( nextval('SAMPLE_ANALYTE_STATUS_HIST_SEQ'), new.sample_result_id, new.STATUS_CODE, new.status_date, new.status_user_id );
  END IF;

  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER TRG_SAMPLE_ANALYTE_STATUS_HIST
    AFTER INSERT OR UPDATE ON SAMPLE_RESULTS
    FOR EACH ROW
    EXECUTE PROCEDURE SAMPLE_STATUS_HISTORY_Trigger()
;

我确保触发器已绑定到表。

主要应用程序是使用NHibernate的.NET MVC应用程序。事务在事务中起作用,但是事务在主表的插入/更新中起作用。

我唯一的猜测是,我在触发逻辑中存在语法错误,但是如果我手动运行插入或更新语句,就不会看到该错误。

2 个答案:

答案 0 :(得分:0)

对于insertOLD.?为null,因此不等式检查也将返回null。

相反,使用

IF( old.STATUS_CODE IS DISTINCT FROM new.STATUS_CODE ) THEN

答案 1 :(得分:0)

对于 old。 值为 null 的INSERT在我尝试@JGH的建议时引起了我的问题。我最终得到了这感觉很脏的代码:

  IF( TG_OP = 'INSERT' OR old.STATUS_CODE <> new.STATUS_CODE ) THEN

我仍然不明白为什么原始代码对UPDATE语句不起作用。两者之间的唯一区别是!= 。也许这是plpgsql的语法问题?

无论哪种方式,这似乎都可以在SQL窗口和应用程序中使用。