【问题标题】:Postgres 'after insert or update' trigger isn't firingPostgres“插入或更新后”触发器未触发
【发布时间】:2020-06-10 00:31:19
【问题描述】:

我已将我们的数据库从 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 应用程序。事物在事务中工作,但事务正在为主表的插入/更新工作。

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

【问题讨论】:

  • 我在这里没有看到问题说明。

标签: postgresql database-trigger


【解决方案1】:

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

改为使用

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

【讨论】:

  • 我认为代码仍然适用于 UPDATE 语句,对吧?我不这么认为。但是-我也会尝试一下,看看它是否有效。
  • 这适用于 UPDATE 但在 INSERT 上出错:SQL 错误:错误:尚未分配记录“旧”详细信息:尚未分配记录的元组结构是不确定的。其中:PL/pgSQL 函数 SAMPLE_STATUS_HISTORY_Trigger() IF 的第 3 行
【解决方案2】:

当我尝试@JGH 的建议时,old. 具有 null 值的 INSERT 给我带来了问题。我最终得到了这段代码,感觉很脏:

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

我仍然不明白为什么原始代码不适用于 UPDATE 语句。这个和那个之间的唯一区别是 !=。也许这是 plpgsql 的语法问题?

无论是哪种方式,这似乎都适用于 SQL 窗口和应用程序。

【讨论】:

    猜你喜欢
    • 2016-10-13
    • 2021-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-24
    • 1970-01-01
    • 2019-07-28
    相关资源
    最近更新 更多