繁体   English   中英

PSQL 数据库更新触发器更新程序有效。 但是插入过程没有

[英]PSQL Database Update trigger update procedure works. But insert procedure doesn't

我目前正在尝试为我的 rails 应用程序实现 Postgres 文本搜索。 我的迁移成功运行,创建了所有表。 我的一个迁移添加了一个触发器来更新我的列表表上的 ts_vector 列 (TSV)。 它在表上执行一堆连接,在中间表上执行两个连接。 不确定这个触发器是否最有效,但它在被过程调用时有效。

CREATE OR REPLACE FUNCTION update_listings_tsv() RETURNS trigger AS $$
BEGIN
 NEW.tsv := (
   SELECT
     setweight(to_tsvector(l.item_name), 'A') ||
     setweight(to_tsvector(l.description), 'B') ||
     setweight(to_tsvector(categories.name), 'B') ||
     setweight(to_tsvector(sub_categories.name), 'B') ||
     setweight(to_tsvector(sizes.name), 'B') ||
     setweight(to_tsvector(users.username), 'C') ||
     setweight(to_tsvector(string_agg(DISTINCT brands.name, ',')), 'A') ||
     setweight(to_tsvector(string_agg(DISTINCT colours.name, ',')), 'B')


   FROM listings l
   JOIN users ON users.id = l.user_id
   JOIN categories ON categories.id = l.category_id
   JOIN sub_categories ON sub_categories.id = l.sub_category_id
   JOIN sizes ON sizes.id = l.size_id
   JOIN conditions ON conditions.id = l.condition_id


   JOIN brands_listings ON brands_listings.listing_id = l.id
   JOIN brands ON brands.id = brands_listings.brand_id

   JOIN colours_listings ON colours_listings.listing_id = l.id
   JOIN colours ON colours.id = colours_listings.colour_id


   WHERE l.id = NEW.id
   GROUP BY l.id, users.id, categories.id, sub_categories.id, sizes.id, conditions.id
 );
 RETURN NEW;
END;
$$ LANGUAGE plpgsql;

这就是问题所在:

调用触发器的更新过程工作正常。 正如预期的那样,当列表列更新时,该确切列表的 TSV 列也会更新。

CREATE TRIGGER tsvectorupdateupdate BEFORE UPDATE
ON listings FOR EACH ROW EXECUTE PROCEDURE update_listings_tsv();

插入过程不起作用。 我已经用 BEFORE 和 AFTER INSERT 试过了。 我不知道问题出在哪里。 在 db:reset 之后,TSV 列应该已经填充了 ts_vector 值。

CREATE TRIGGER tsvectorupdateinsert AFTER INSERT OR UPDATE
ON listings FOR EACH ROW EXECUTE PROCEDURE update_listings_tsv(tsv);

如果您执行 AFTER 触发器,则更改该值为时已晚。 如果您执行 BEFORE 触发器,则现在加入表“listings”中的(尚不存在的)行还为时过早。 您需要从 NEW,而不是从“列表”中获取新数据。

我已将其简化为最低限度的本质,用额外的表和列充实它取决于您:

CREATE OR REPLACE FUNCTION update_listings_tsv() RETURNS trigger AS $$
BEGIN
 NEW.tsv := (
   SELECT
     setweight(to_tsvector(NEW.item_name), 'A') ||
     setweight(to_tsvector(users.username), 'C')
   FROM users where users.id = NEW.user_id   
 );
 RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER tsvectorupdateinsert BEFORE INSERT OR UPDATE    
ON listings FOR EACH ROW EXECUTE PROCEDURE update_listings_tsv();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM