【发布时间】:2021-10-26 20:40:59
【问题描述】:
我正在尝试在 Postgres 13 中创建一个触发器函数,在插入或更新操作完成之前,它将值从两列复制到另外两列。
在更新/插入操作之前,我的表 test.run_conf 如下所示:
| hostname | run_config_current | run_config_current_hash | run_config_last | run_config_last_hash |
|---|---|---|---|---|
| switch01 | old_txt_str | 32314322 |
当发生更新/插入时,我希望将 run_config_current 中的值复制到 run_config_last 并将 run_config_current_hash 复制到 run_config_last_hash。然后允许对列 run_config_current 进行更新/插入操作 - 之后触发器函数将重新计算 run_config_current_hash 的值。
为了测试,我运行以下查询将新数据插入到列run_config_current:
INSERT INTO test.run_conf (hostname, run_config_current) VALUES ('switch01', 'new_txt_str' )
ON CONFLICT (hostname) DO UPDATE SET run_config_current = excluded.run_config_current
但是发生的情况是表 test.run_conf 更新如下 - 新值被插入到 run_config_current 和 run_config_last 两列中:
| hostname | run_config_current | run_config_current_hash | run_config_last | run_config_last_hash |
|---|---|---|---|---|
| switch01 | new_txt_str | 47173234 | new_txt_str | 32314322 |
我现在没有正常工作的触发器和功能是:
CREATE OR REPLACE FUNCTION test.run_conf_hash_gen_func()
RETURNS TRIGGER
SET SCHEMA 'test'
LANGUAGE plpgsql
AS $$
BEGIN
NEW.run_config_last := NEW.run_config_current;
NEW.run_config_last_hash := NEW.run_config_current_hash;
NEW.run_config_current_hash := MD5(NEW.run_config_current);
RETURN NEW;
END;
$$
CREATE TRIGGER run_conf_hash_gen_trig
BEFORE INSERT OR UPDATE on test.run_conf
FOR EACH ROW
EXECUTE PROCEDURE test.run_conf_hash_gen_func();
请帮助我理解为什么我的代码似乎将run_config_current 的新值复制到run_config_last。谢谢!
【问题讨论】:
-
因为在执行
UPDATE时需要OLD.run_config_current。这意味着在触发函数中,您需要区分INSERT或UPDATE,因为INSERT没有OLD值。请参阅TG_OP此处plpgsql trigger function。 -
原来在 Postgres 11+
OLDforINSERT设置为NULL所以你不必防范OLD的 pre-11 行为在 @987654351 中未分配@.
标签: postgresql triggers