【问题标题】:IF condition evaluation in AFTER TRIGGER function on PostgreSQLPostgreSQL 上的 AFTER TRIGGER 函数中的 IF 条件评估
【发布时间】:2022-09-24 18:00:31
【问题描述】:

我正在 PostgreSQL(版本 10)中编写一个由 TRIGGER 调用的 plpgsql 函数更新

  CREATE TRIGGER trigger_1
   AFTER UPDATE
   ON entities
   FOR EACH ROW
   WHEN ( condition_on_new_and_old )
   EXECUTE PROCEDURE function_1();

实体是一个表,它有一个 JSONB 类型的列 data

function_1 的代码本质上是(我修改了代码以隔离 IF 中的 RAISE,原本条件是相反的):

CREATE OR REPLACE FUNCTION function_1() RETURNS TRIGGER AS
$$
BEGIN
  IF (
       TG_OP <> \'UPDATE\' 
       OR TG_WHEN <> \'AFTER\'
       OR NOT (NEW.data ? \'XXX\')
       OR NOT (OLD.data ? \'XXX\')
       OR NOT (NEW.object_id = OLD.object_id)
       OR NOT (NEW.workspace = OLD.workspace)) THEN

         RAISE EXCEPTION \'XXX not found\';

  END IF;

  -- SOME INSERTs

  -- SOME DELETEs

  RETURN NULL;
END
$$ LANGUAGE plpgsql;

正如每个人都可以预料的那样,如果 IF 中的条件为真,我们将引发异常。问题是无论条件值如何,都会始终执行 RAISE。在我所有的测试中,OLD 和 NEW 的值总是相同的。

更令人惊讶的是,如果我做了类似的事情

CREATE OR REPLACE FUNCTION function_1() RETURNS TRIGGER AS
$$
BEGIN
  IF (
       TG_OP <> \'UPDATE\' 
       OR TG_WHEN <> \'AFTER\'
       OR NOT (NEW.data ? \'XXX\')
       OR NOT (OLD.data ? \'XXX\')
       OR NOT (NEW.object_id = OLD.object_id)
       OR NOT (NEW.workspace = OLD.workspace)) THEN

         RAISE EXCEPTION \'XXX not found\';

  END IF;

  RAISE EXCEPTION \'TEST\'

  -- SOME INSERTs

  -- SOME DELETEs

  RETURN NULL;
END
$$ LANGUAGE plpgsql;

我提出了异常 \'TEST\' 但如果我写道:

CREATE OR REPLACE FUNCTION function_1() RETURNS TRIGGER AS
$$
BEGIN
  IF (
       TG_OP <> \'UPDATE\' 
       OR TG_WHEN <> \'AFTER\'
       OR NOT (NEW.data ? \'XXX\')
       OR NOT (OLD.data ? \'XXX\')
       OR NOT (NEW.object_id = OLD.object_id)
       OR NOT (NEW.workspace = OLD.workspace)) THEN

         RAISE EXCEPTION \'XXX not found\';

  END IF;

  -- RAISE EXCEPTION \'TEST\' (I commented the RAISE)

  -- SOME INSERTs

  -- SOME DELETEs

  RETURN NULL;
END
$$ LANGUAGE plpgsql;

我抛出了异常 \'XXX not found\'。

要注意触发器曾经在 BEFORE UPDATE 上并且它确实按预期工作,当我们将其设置为 AFTER 时问题就出现了。

我很确定我错过了一些关于 AFTER 触发器的行为方式的信息。你有什么想法?

谢谢大家

  • 执行RAISE NOTICE 以显示您在IF 条件中使用的所有变量。
  • 还要提供您正在使用的 UPDATE 数据。
  • 您能否分享有关WHEN ( condition_on_new_and_old ) 的更多信息。您的代码按预期工作。
  • dbfiddle.uk/fnM7Y0Us我的测试演示。

标签: sql postgresql if-statement triggers


【解决方案1】:

感谢有关问题的cmets。很抱歉,但我没有在日志中注意到 TRIGGER 的WHEN 条件实际上存在问题。

修好后就可以工作了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多