在 insert/update 上触发不更新 tsvector
Trigger not updating tsvector on insert/update
我正在尝试从几个表中的几个列中提取数据以使其可全文搜索,但我的运气不佳。
这是我的函数:
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 列在 inserts/updates.
之后是空白的
当我手动 运行 大部分功能时,它按预期工作。
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 还很陌生。我错过了什么?
当触发器运行 BEFORE INSERT 或 UPDATE 时,从 table select 获取新值是有缺陷的,因为新值还没有。
考虑这部分查询:
SELECT concat("name", ' ', "phone") as text
FROM "Customers"
where "id" = NEW.id
对于 INSERT,您将始终在此处获得 NULL,而对于 UPDATE,您将获得即将被替换的值,而不是新值。
上面代码的替代品应该是:
SELECT (NEW.name || ' ' || NEW.phone) AS text
另一点看起来可疑的是:如果 3 table 中任何一个的用户详细信息中的任何字段为 NULL,则整个连接的内容将为空,因为代码适用coalesce
在最后而不是在每个单独的字段上进行。
我正在尝试从几个表中的几个列中提取数据以使其可全文搜索,但我的运气不佳。
这是我的函数:
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 列在 inserts/updates.
之后是空白的当我手动 运行 大部分功能时,它按预期工作。
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 还很陌生。我错过了什么?
当触发器运行 BEFORE INSERT 或 UPDATE 时,从 table select 获取新值是有缺陷的,因为新值还没有。
考虑这部分查询:
SELECT concat("name", ' ', "phone") as text
FROM "Customers"
where "id" = NEW.id
对于 INSERT,您将始终在此处获得 NULL,而对于 UPDATE,您将获得即将被替换的值,而不是新值。
上面代码的替代品应该是:
SELECT (NEW.name || ' ' || NEW.phone) AS text
另一点看起来可疑的是:如果 3 table 中任何一个的用户详细信息中的任何字段为 NULL,则整个连接的内容将为空,因为代码适用coalesce
在最后而不是在每个单独的字段上进行。