对整个事务执行 Postgres 触发器,而不是对每个更新操作执行
Execute Postgres Trigger on an entire transaction and not for each update operation
我想知道是否可以基于事务在 PostgreSql 中强制执行触发器。
我正在从 python 脚本(从 for 循环内)更新记录。有一个触发器在更新操作时将记录插入 table。现在,我只想根据整个交易插入一条记录,而不是针对我在 python 脚本中更新的每条记录。
有没有办法做到这一点?
它有点笨拙,但您可以使用条件触发器来做到这一点:
CREATE TRIGGER t
AFTER UPDATE ON MyTable
FOR EACH ROW
WHEN (IsFirstCallForThisTransaction())
EXECUTE PROCEDURE MyTrigger();
棘手的一点是定义 IsFirstCallForThisTransaction()
。在内部,它需要在某处设置一个标志,但我们还需要保证该标志作用于当前事务。
一种选择是使用 SET LOCAL
to assign a custom configuration variable。您可以通过将此行服务器的 postgresql.conf
文件放入来初始化此变量:
my_vars.trigger_called_in_current_transaction = false
或者,将默认值附加到相关数据库:
ALTER DATABASE MyDB SET my_vars.trigger_called_in_current_transaction = false;
那么函数看起来像这样:
CREATE FUNCTION IsFirstCallForThisTransaction() RETURNS BOOLEAN AS
$BODY$
BEGIN
IF current_setting('my_vars.trigger_called_in_current_transaction')::boolean THEN
RETURN false;
ELSE
SET LOCAL my_vars.trigger_called_in_current_transaction TO true;
RETURN true;
END IF;
END
$BODY$
LANGUAGE plpgsql VOLATILE;
我想知道是否可以基于事务在 PostgreSql 中强制执行触发器。
我正在从 python 脚本(从 for 循环内)更新记录。有一个触发器在更新操作时将记录插入 table。现在,我只想根据整个交易插入一条记录,而不是针对我在 python 脚本中更新的每条记录。
有没有办法做到这一点?
它有点笨拙,但您可以使用条件触发器来做到这一点:
CREATE TRIGGER t
AFTER UPDATE ON MyTable
FOR EACH ROW
WHEN (IsFirstCallForThisTransaction())
EXECUTE PROCEDURE MyTrigger();
棘手的一点是定义 IsFirstCallForThisTransaction()
。在内部,它需要在某处设置一个标志,但我们还需要保证该标志作用于当前事务。
一种选择是使用 SET LOCAL
to assign a custom configuration variable。您可以通过将此行服务器的 postgresql.conf
文件放入来初始化此变量:
my_vars.trigger_called_in_current_transaction = false
或者,将默认值附加到相关数据库:
ALTER DATABASE MyDB SET my_vars.trigger_called_in_current_transaction = false;
那么函数看起来像这样:
CREATE FUNCTION IsFirstCallForThisTransaction() RETURNS BOOLEAN AS
$BODY$
BEGIN
IF current_setting('my_vars.trigger_called_in_current_transaction')::boolean THEN
RETURN false;
ELSE
SET LOCAL my_vars.trigger_called_in_current_transaction TO true;
RETURN true;
END IF;
END
$BODY$
LANGUAGE plpgsql VOLATILE;