提问人:dariush624 提问时间:9/23/2022 更新时间:9/24/2022 访问量:110
PostgreSQL 上 AFTER TRIGGER 函数中的 IF 条件计算
IF condition evaluation in AFTER TRIGGER function on PostgreSQL
问:
我正在 PostgreSQL(版本 10)中编写一个 plpgsql 函数,该函数在 UPDATE 后由 TRIGGER 调用
CREATE TRIGGER trigger_1
AFTER UPDATE
ON entities
FOR EACH ROW
WHEN ( condition_on_new_and_old )
EXECUTE PROCEDURE function_1();
entities 是一个表,它有一个 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 触发器行为的信息。你有什么想法吗?
提前谢谢大家
答:
0赞
dariush624
9/24/2022
#1
感谢您对这个问题的评论。对不起,但我没有在日志中注意到 TRIGGER 的状况实际上存在问题。WHEN
修复它后,它就可以工作了。
评论
RAISE NOTICE
IF
WHEN ( condition_on_new_and_old )