gor*_*ori 7 database postgresql triggers postgresql-9.5
我需要临时禁用一个事务中的一个postgreSQL触发器,但没有硬件锁定表,有人知道是否可能
这样的事情,但没有锁定表和禁止在此事务之外的触发器
BEGIN TRANSACTION;
ALTER TABLE foo DISABLE TRIGGER bar;
-- DO SOME UPDATES ON foo
UPDATE foo set field = 'value' where field = 'test';
ALTER TABLE foo ENABLE TRIGGER bar;
COMMIT;
Run Code Online (Sandbox Code Playgroud)
Ale*_*ore 10
我遇到了同样的问题,并找到了一种聪明而干净的方法来解决它。
\n首先,如果当前正在执行触发器,则不能禁用触发器内的触发器。这是我的场景 - 我由于插入到表中而插入到表中 - 否则会导致触发器无限循环。
\n我解决这个问题的方法是在混合中添加一个本地参数变量,该变量本质上充当全局变量,当触发器已经被使用时,它将禁用触发器的进一步调用。
\n为此,请在触发器函数的最开始添加以下代码:
\nSET LOCAL your.variable_name to 'TRUE';
然后(假设您正在使用 pg \xe2\x89\xa5 9.6)您只需将以下行添加到您的CREATE TRIGGER:
WHEN (current_setting('your.variable_name', 't') <> 'TRUE')
我还没有做过任何基准测试,但根据我之前的经验,我希望它的性能非常好。
\n更新:
\n我已经在一个高度活跃的数据仓库中使用这种方法好几年了,现在默认情况下在我的所有触发器(可能有 50 个)上设置了它。我已经将代码形式化为:
\nCREATE OR REPLACE FUNCTION trigger_state(\n IN setting_name TEXT\n) RETURNS BOOLEAN AS\n$$\nBEGIN\n\nRETURN coalesce(NOT upper(current_setting(setting_name, TRUE)) = 'DISABLED',TRUE);\n\nEND\n$$\nLANGUAGE plpgsql\nSTABLE\n;\nRun Code Online (Sandbox Code Playgroud)\n并像这样使用它:
\nCREATE TRIGGER some_trigger\n BEFORE INSERT\n ON some_table\n FOR EACH ROW\n WHEN (\n trigger_state('some_domain_name.trigger_state.some_trigger')\n AND OLD.some_column IS DISTINCT FROM NEW.some_column\n )\n EXECUTE FUNCTION some_trg_funct()\n;\n\n\nRun Code Online (Sandbox Code Playgroud)\n要禁用触发器(出于任何原因),无论是在代码还是命令行中,只需:
\nSET "some_domain_name.trigger_state.some_trigger" = 'DISABLED';
正如您所期望的语法一样,这适用于事务、会话等SET。它不受锁定或类似情况的影响,并且在当前会话/范围内立即生效。
注意:然而,其影响在全球范围内是不可预测的(尤其是在短期内)。如果您需要全局禁用触发器,那么最好的方法是使用上面提到的规范方法。
\n不管怎样,它对我来说非常有帮助。我除了成功之外一无所有——至少就我后来能够讲述的大量交易而言是这样。
\n您可以禁用此表中的所有触发器。它应该是这样的:
ALTER TABLE tblname DISABLE TRIGGER USER;
Your SQL;
ALTER TABLE tblname ENABLE TRIGGER USER;
Run Code Online (Sandbox Code Playgroud)
要禁用单个触发器,请使用以下命令:
ALTER TABLE tblname DISABLE TRIGGER trigger_name;
Your SQL;
ALTER TABLE tblname ENABLE TRIGGER trigger_name;
Run Code Online (Sandbox Code Playgroud)
您可以在文档中阅读有关ALTER TABLE 的更多信息。
要临时禁用PostgreSQL会话中的所有触发器,请使用以下命令:
SET session_replication_role = replica;
Run Code Online (Sandbox Code Playgroud)
这将仅禁用当前数据库会话的所有触发器.对于批量操作很有用,但请记住要小心保持数据库的一致性.
要重新启用:
SET session_replication_role = DEFAULT;
Run Code Online (Sandbox Code Playgroud)
来源:http://koo.fi/blog/2013/01/08/disable-postgresql-triggers-temporarily/