我正在尝试在 PostgreSQL 9.2 中设置全文搜索。我创建了一个新表来保存我想要搜索的内容(这样我就可以搜索很多不同类型的项目),它看起来像这样:
CREATE TABLE search (
target_id bigint PRIMARY KEY,
target_type text,
fts tsvector
);
CREATE INDEX search_fts ON search USING gin(fts);
每次将新项目插入(或更新)到我要搜索的各种表之一时,它应该自动添加到 search
表中。假设我的表格如下所示:
CREATE TABLE item (id bigint PRIMARY KEY, name text NOT NULL, description text);
我创建了一个触发器,传入我希望能够搜索的列名:
CREATE TRIGGER insert_item_search BEFORE INSERT
ON item FOR EACH ROW EXECUTE PROCEDURE
insert_search('{name, description}'::text[]);
然后创建了一个新函数 insert_search
如下:
CREATE OR REPLACE FUNCTION insert_search(cols text[]) RETURNS TRIGGER AS $$
BEGIN
INSERT INTO search (target_id, target_type, fts) VALUES (
NEW.id, TG_TABLE_NAME, to_tsvector('english', 'foo')
);
RETURN NEW;
END;
$$ LANGUAGE PLPGSQL;
我的问题是,如何将基于 cols
的表值传递给 to_tsvector
?现在,正在调用该函数并正确插入 id
和 type
,但我不知道根据 动态获取其他值的正确方法>cols
参数。
最佳答案
首先,要传递参数,直接发送即可:
CREATE TRIGGER insert_item_search BEFORE INSERT
ON item FOR EACH ROW EXECUTE PROCEDURE
insert_search('name', 'description');
并且,从 PL/pgSQL 中,您将以数组形式获取这些参数,称为 TG_ARGV
。但是,问题是 PL/pgSQL 无法根据名称从 NEW
记录中获取值。为此,您可以使用允许您这样做的语言(如 PL/python 或 PL/perl)或使用 hstore
extension .
我会坚持使用最后一个并使用 hstore
(除非您已经使用其他语言之一来创建函数):
CREATE OR REPLACE FUNCTION insert_search() RETURNS TRIGGER AS $$
DECLARE
v_new hstore;
BEGIN
v_new = hstore(NEW); -- convert the record to hstore
FOR i IN 0..(TG_NARGS-1) LOOP
INSERT INTO search (target_id, target_type, fts) VALUES (
NEW.id, TG_TABLE_NAME, to_tsvector('english', v_new -> TG_ARGV[i])
);
END LOOP;
RETURN NEW;
END;
$$ LANGUAGE PLPGSQL;
正如您在上面看到的,我使用了 hstore
的运算符 ->
来获取基于名称的值(在 TG_ARGV[i]
)。
关于postgresql - 根据传递给 PostgreSQL 函数的列名数组获取行值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15030890/