如何将 postgres 函数重用于触发器和一般用途
How to reuse a postgres function for triggers and generic use
确实是非常简单的问题。假设我有一个触发器可以将来自其他 table 的一些文本字段转换为 tsv 索引,这样我就可以以一种高效的方式实现全文搜索。
为了实现这一点,我有:
- 创建了一个函数来执行我想要的 SQL 查询(有效)
- 创建了一个触发器,在我的 ordering.order table 更新(有效)时调用该函数
- 尝试在触发器之前重用相同的函数,因为我也想更新旧数据(不起作用)
migration failed: trigger functions can only be called as triggers
简而言之,在 postgres 函数中是否有任何 return 类型允许我既可以在触发器中使用它又可以在其他地方作为普通函数调用?非常感谢。
CREATE OR REPLACE FUNCTION index_text_fields() RETURNS trigger AS $$
BEGIN
UPDATE ordering.order as uo SET tsv = setweight(to_tsvector
(coalesce(s.name, '')), 'A')
|| setweight(to_tsvector(coalesce(split_part(o.order_ref,'-',2),'')), 'A')
FROM ordering.order AS o
LEFT JOIN ordering.sender AS s USING (order_id)
LEFT JOIN ordering.receiver AS r USING (order_id)
WHERE uo.order_id = o.order_id;
RETURN NULL;
END
$$ LANGUAGE plpgsql;
DO $$ BEGIN
PERFORM index_text_fields();
END $$;
CREATE TRIGGER orders_trigger AFTER
INSERT OR UPDATE
ON ordering.order FOR EACH ROW
WHEN (pg_trigger_depth() < 1)
EXECUTE PROCEDURE index_text_fields();
对这两个任务使用相同的函数没有意义。
对于触发器,您将使用 BEFORE
触发器,触发器函数不会修改 table,而是分配给 NEW.tsv
和return NEW
.
要更新现有数据,您需要 UPDATE
语句。
确实是非常简单的问题。假设我有一个触发器可以将来自其他 table 的一些文本字段转换为 tsv 索引,这样我就可以以一种高效的方式实现全文搜索。
为了实现这一点,我有:
- 创建了一个函数来执行我想要的 SQL 查询(有效)
- 创建了一个触发器,在我的 ordering.order table 更新(有效)时调用该函数
- 尝试在触发器之前重用相同的函数,因为我也想更新旧数据(不起作用)
migration failed: trigger functions can only be called as triggers
简而言之,在 postgres 函数中是否有任何 return 类型允许我既可以在触发器中使用它又可以在其他地方作为普通函数调用?非常感谢。
CREATE OR REPLACE FUNCTION index_text_fields() RETURNS trigger AS $$
BEGIN
UPDATE ordering.order as uo SET tsv = setweight(to_tsvector
(coalesce(s.name, '')), 'A')
|| setweight(to_tsvector(coalesce(split_part(o.order_ref,'-',2),'')), 'A')
FROM ordering.order AS o
LEFT JOIN ordering.sender AS s USING (order_id)
LEFT JOIN ordering.receiver AS r USING (order_id)
WHERE uo.order_id = o.order_id;
RETURN NULL;
END
$$ LANGUAGE plpgsql;
DO $$ BEGIN
PERFORM index_text_fields();
END $$;
CREATE TRIGGER orders_trigger AFTER
INSERT OR UPDATE
ON ordering.order FOR EACH ROW
WHEN (pg_trigger_depth() < 1)
EXECUTE PROCEDURE index_text_fields();
对这两个任务使用相同的函数没有意义。
对于触发器,您将使用
BEFORE
触发器,触发器函数不会修改 table,而是分配给NEW.tsv
和returnNEW
.要更新现有数据,您需要
UPDATE
语句。