根据传递给PostgreSQL函数的列名数组获取行值

时间:2013-02-22 18:33:44

标签: postgresql

我正在尝试在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?现在,函数被调用并正确插入idtype,但我不知道基于cols参数动态获取其他值的正确方法。 / p>

2 个答案:

答案 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]等等。