gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-29 13:02:53 25 4
gpt4 key购买 nike

我在 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 expression 的子查询中提供多行使其成为单个 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 中那样派生列类型。没有引号的只有数字的数字默认为 integer(bigint/numeric 如果太大)。

您仍然可以使用准备好的语句(带有许多参数)。对于大量行,宁愿切换到批量加载到临时暂存表并从那里更新:
How to update selected rows with values from a CSV file in Postgres?

更多选项:
How to UPDATE table from csv file?

关于sql - 如何避免为准备好的语句的每一行启动触发器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23897289/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com