簡體   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