![](/img/trans.png)
[英]Rails 3.1, after_update procedure doesn't accept method parameters?
[英]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.