如何分隔 PostgreSQL 触发器过程名称?

How to delimit PostgreSQL trigger procedure name?

例如,在 Perl 中,您可以像这样分隔变量:

${foo}_bar

我在 PostgreSQL 中有一个触发器是从 here 借来的,我正试图使其通用以与多个 table 一起使用。这是我的代码:

CREATE OR REPLACE FUNCTION update_parent_path() RETURNS TRIGGER AS $$
DECLARE
    PATH ltree;
BEGIN
    IF NEW.parent_id IS NULL THEN
        NEW.parent_path = 'root'::ltree;
    ELSEIF TG_OP = 'INSERT' OR OLD.parent_id IS NULL OR OLD.parent_id != NEW.parent_id THEN
        SELECT parent_path || TG_TABLE_NAME_id::text FROM TG_TABLE_NAME WHERE TG_TABLE_NAME_id = NEW.parent_id INTO PATH;
        IF PATH IS NULL THEN
            RAISE EXCEPTION 'Invalid parent_id %', NEW.parent_id;
        END IF;
        NEW.parent_path = PATH;
    END IF;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

我使用此触发器的每个 table 都有一个主键,如 table_id(例如,skill_id、level_id 等)。我想做的是说 WHERE skill_id = NEW.parent_id(不管它被调用的是什么 table),因此我说 WHERE TG_TABLE_NAME_id = NEW.parent_id 的原因。我想知道的是如何从 _id 中分隔 TG_TABLE_NAME(触发程序)?

或者,有更好的方法吗?也许我只是在做这一切都错了。

PLpgSQL 有一个基本规则 - plpgsql 变量不能用作嵌入式 SQL 中的 table 名称或列名称。但是有一个动态的 SQL - 下一步,如何执行 SQL 查询。动态 SQL 是在运行时从字符串(或字符串表达式)生成的查询。 PLpgSQL 变量可以在任何地方使用。所以你的查询片段:

SELECT TG_TABLE_NAME_id::text FROM TG_TABLE_NAME ...

在更多方面是错误的,应该永远行不通。但是动态查询(PLpgSQL语句EXECUTE)应该可以工作

EXECUTE format('SELECT %I FROM %I ...', 
                TG_TABLE_NAME || '_id', TG_TABLE_NAME) INTO path;

相关文档:http://www.postgresql.org/docs/9.4/static/plpgsql-statements.html#PLPGSQL-STATEMENTS-EXECUTING-DYN