我有一个通过逻辑复制连接的两个 postgresql 数据库的测试场景。数据库“A”正在发布表“a1”的插入和更新,并且数据库“B”已订阅并毫无问题地接收所有内容。
我在更新数据库“B”上的表“a1”之前添加了一个触发器。它适用于在“B”上本地执行的更新语句,但当通过逻辑复制进行更新时它不会触发。这是我用来测试它的函数和触发器。
CREATE OR REPLACE FUNCTION update_tg_func()
RETURNS TRIGGER AS $$
BEGIN
-- Extract the id value from the update query
-- Assuming that the 'id' column is being updated
RAISE WARNING 'Got OP %, id %', TG_OP, NEW.id;
-- For other operations, just return the NEW row
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER update_tg
BEFORE UPDATE ON a1
FOR EACH STATEMENT
EXECUTE FUNCTION update_tg_func();
ALTER TABLE a1 ENABLE ALWAYS TRIGGER update_tg ;
Postgres 版本是 12.1,未在较新版本中进行测试。
编辑
感谢@Melkij,我注意到我的触发器没有触发,因为我的表是空的。我的表是空的,因为我有另一个触发器BEFORE INSERT
,可以将插入的行“重定向”到其他表,就像分区一样,但不使用真正的分区。
我认为FOR EACH STATEMENT
即使没有行受到影响,使用也会触发触发器。文档说:
标记为任何给定操作仅执行一次的触发器
FOR EACH STATEMENT
,无论它修改了多少行 https://www.postgresql.org/docs/12/sql-createtrigger.html
我删除了“重定向”插入行的触发器,因此 DB B 上的表有一些行,现在触发器确实会触发。
即使表为空,我也需要触发器来触发。有什么提示吗?
可能很难找到,但它记录在此处
虽然,看看
NEW.id
在触发器函数中使用的尝试,我认为您想创建一个FOR EACH ROW
触发器而不是FOR EACH STATEMENT
. 尝试使用行触发器:PS:这么多年忽略小更新真是一个糟糕的主意。考虑安装12.18