我们有一个昂贵的
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 触发器中的特定列是否已更改,您可以迭代每对新旧行,并使用
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();