对整个事务执行Postgres触发器,而不是对每个更新操作

时间:2016-06-30 14:17:07

标签: database postgresql postgresql-9.3 postgresql-9.4

我想知道是否可以根据事务强制在PostgreSql中执行触发器。

我正在从python脚本更新记录(来自for循环)。有一个触发器在更新操作时将记录插入表中。现在,我只想根据整个事务插入一条记录,而不是我在python脚本中更新的每条记录。

有没有办法可以做到这一点?

1 个答案:

答案 0 :(得分:0)

它有点笨重,但你可以用条件触发器来做到这一点:

CREATE TRIGGER t
AFTER UPDATE ON MyTable
FOR EACH ROW
WHEN (IsFirstCallForThisTransaction())
EXECUTE PROCEDURE MyTrigger();

棘手的一点是定义IsFirstCallForThisTransaction()。在内部,它需要在某处设置标志,但我们还需要保证此标志的作用域为当前事务。

一种选择是使用SET LOCAL分配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;