我正在尝试在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
参数动态获取其他值的正确方法。 / p>
答案 0 :(得分:5)
首先,要传递参数,只需直接发送:
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]
)获取值。
答案 1 :(得分:0)
您可以使用TG_ARGV
变量访问触发器定义中指定的参数。您可以找到here的文档。 TG_ARGV
是由基于0的索引访问的数组。所以它会像TG_ARGV[0]
,TG_ARGV[1]
等等。