繁体   English   中英

如何避免为准备好的语句的每一行启动触发器?

[英]How to avoid launching a trigger for every row of a prepared statement?

我在table1上有一个FOR EACH STATEMENT触发器:

CREATE TRIGGER trg_table1 AFTER INSERT OR DELETE OR UPDATE OF field1 ON table1
FOR EACH STATEMENT EXECUTE PROCEDURE my_trigger_procedure();

我必须按如下方式更新该表的行:

UPDATE table1 SET field1='abc' WHERE field5=1;
UPDATE table1 SET field1='def' WHERE field5=2;
UPDATE table1 SET field1='ghi' WHERE field5=3;
...

为了清楚起见,名称和值被简化。

每个UPDATE被视为一条语句,因此将为这些行中的每一行触发该触发器。

为了避免这种情况,我做了准备发言:

PREPARE my_prep_stmnt AS
UPDATE table1
SET
field1=$1
WHERE field5=$2
;

EXECUTE my_prep_stmnt ('abc',1);
EXECUTE my_prep_stmnt ('def',2);
EXECUTE my_prep_stmnt ('ghi',3);

我期望仅在准备好的语句完成后才触发触发器,但不,触发器针对每个EXECUTE行都触发。

问题是触发过程需要时间才能执行。 有什么想法可以解决吗?

在子查询中使用VALUES表达式提供多行以使其成为单个 UPDATE语句:

UPDATE table1 t
SET    field1 = u.field1
FROM (
   VALUES
    ('abc'::text, 1)   -- cast string literal in row 1 to make type unambiguous
   ,('def', 2)
   ,('ghi', 3)
   ) u (field1, filed5)
WHERE  t.field5 = u.field5;

您需要强制转换为匹配类型,因为VALUES表达式是独立的,不能像UPDATE中那样派生列类型。 仅带数字的未加引号的数字默认为integerbigint / numeric如果太大)。

您仍然可以使用准备好的语句(带有许多参数)。 对于大量行,请改用批量加载到临时登台表并从那里进行更新:
如何使用Postgres中CSV文件中的值更新所选行?

更多选择:
如何从csv文件更新表?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM