Postgres:获取 FOR EACH STATEMENT 触发器中更新的列的列表

问题描述 投票:0回答:1

我们有一个昂贵的

AFTER UPDATE...FOR EACH STATEMENT
触发函数,可以填充用于搜索的
tsvector
列。

有一个可搜索的列子集,并且是

tsvector
一代的一部分。

由于我们无法在

CREATE TRIGGER
中为语句级触发器指定列列表,有没有办法找出针对当前
UPDATE
语句更新的列,以便我们仅在以下情况之一时重新生成
tsvector
:可搜索栏已更新?

编辑:

UPDATE
语句可以一次性更新1行或50K行。

Edit2:似乎是以下问题的重复。我会在以后将其添加到 Postgres 中的任何新功能中保持打开状态一段时间。

https://dba.stackexchange.com/questions/290005/how-to-select-sub-object-with-given-keys-from-jsonb

postgresql triggers
1个回答
0
投票

要使用转换表检查 PostgreSQL 触发器中的特定列是否已更改,您可以迭代每对新旧行,并使用

IS DISTINCT FROM
运算符来比较相关列的值。以下是如何在触发函数中完成此操作的简化示例:

FOR row_old, row_new IN
    SELECT old.*, new.*
    FROM old_table AS old
    JOIN new_table AS new ON old.primary_key = new.primary_key
LOOP
    -- Check if any of the relevant columns have changed
    IF row_old.searchable_column1 IS DISTINCT FROM row_new.searchable_column1
       OR row_old.searchable_column2 IS DISTINCT FROM row_new.searchable_column2
       -- Add more columns as needed
    THEN
        -- Perform tsvector update logic here
    END IF;
END LOOP;

使用触发器

CREATE OR REPLACE FUNCTION my_trigger_function()
RETURNS TRIGGER AS $$
DECLARE
    row_old RECORD;
    row_new RECORD;
    is_changed BOOLEAN;
BEGIN
    -- Iterate over each pair of old and new rows
    FOR row_old, row_new IN
        SELECT * FROM old_table
        JOIN new_table ON old_table.primary_key = new_table.primary_key
    LOOP
        -- Check if any of the relevant columns have changed
        is_changed := row_old.searchable_column1 IS DISTINCT FROM row_new.searchable_column1
                   OR row_old.searchable_column2 IS DISTINCT FROM row_new.searchable_column2
                   -- Add more columns as needed
                   ;

        -- Update tsvector if there is a change in relevant columns
        IF is_changed THEN
            -- Perform tsvector update logic here
        END IF;
    END LOOP;

    RETURN NULL;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER my_trigger
AFTER UPDATE ON my_table
REFERENCING OLD TABLE AS old_table NEW TABLE AS new_table
FOR EACH STATEMENT
EXECUTE FUNCTION my_trigger_function();
© www.soinside.com 2019 - 2024. All rights reserved.