触发不在插入/更新时更新tsvector

时间:2015-09-30 06:28:26

标签: postgresql triggers full-text-search

我正试图通过几个表格中的几列来挖掘数据,使其可以搜索全文,但我没有太多运气。

这是我的功能:

CREATE OR REPLACE FUNCTION on_customer_save_udpate_tsv() RETURNS trigger AS $$ 
declare 
   tsv_text text; 
begin 
SELECT string_agg(cust_text.text, ' ') as agg_text into tsv_text 
FROM (SELECT concat("name", ' ', "phone") as text 
   FROM "Customers" 
   where "id" = NEW.id 
   UNION 
   SELECT concat("firstName", ' ', "lastName", ' ', "phone", ' ', "email") as text 
   FROM "Contacts" 
   where "customerId" = NEW.id 
   UNION 
   SELECT concat("streetLine1", ' ', "city", ' ', "state", ' ', "zip") as text 
   FROM "Addresses" 
   where "customerId" = NEW.id) cust_text; 
NEW.tsv := to_tsvector(coalesce(tsv_text,'')); 
return NEW; 
end 
$$ LANGUAGE plpgsql; 

这是我的触发器:

CREATE TRIGGER cust_tsv_trigger BEFORE INSERT OR UPDATE 
ON "Customers" FOR EACH ROW EXECUTE PROCEDURE on_customer_save_udpate_tsv();

但是,插入/更新后,“Customers”.tsv列为空。

当我手动运行大部分功能时,它会按预期工作。

DO $$ 
declare 
   tsv_text text; 
begin 
SELECT string_agg(cust_text.text, ' ') as agg_text into tsv_text 
FROM (SELECT concat("name", ' ', "phone") as text 
   FROM "Customers" 
   where "id" = 17 
   UNION 
   SELECT concat("firstName", ' ', "lastName", ' ', "phone", ' ', "email") as text 
   FROM "Contacts" 
   where "customerId" = 17
   UNION 
   SELECT concat("streetLine1", ' ', "city", ' ', "state", ' ', "zip") as text 
   FROM "Addresses" 
   where "customerId" = 17) cust_text; 

   UPDATE "Customers"
   SET tsv = to_tsvector(coalesce(tsv_text, ''))
   WHERE "id" = 17;
end 
$$ LANGUAGE plpgsql; 

我对postgres很新。我错过了什么?

1 个答案:

答案 0 :(得分:2)

当触发器运行 BEFORE INSERT或UPDATE时,让它从表中选择以获取新值是有缺陷的,因为新值不存在。

考虑这部分问题:

SELECT concat("name", ' ', "phone") as text 
   FROM "Customers" 
   where "id" = NEW.id 

对于INSERT,你总是在这里得到NULL,如果是UPDATE,你将得到即将被替换的值,而不是新的值。

应该使用什么作为上述代码的替代品:

SELECT (NEW.name || ' ' || NEW.phone) AS text

另一个看起来可疑的点是:如果来自3个表中的任何一个的用户详细信息中的任何字段为NULL,则整个连接的内容将为空,因为代码在{1}处应用coalesce结束而不是在每个单独的领域上做。