如何划分PostgreSQL触发器过程名



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

${foo}_bar

我有一个触发器在PostgreSQL从这里借来的,我正试图使通用的工作与多个表。下面是我的代码:

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_id(例如,skill_id, level_id等)。我要做的是说WHERE skill_id = NEW.parent_id(对于它被调用的任何表),因此我说WHERE TG_TABLE_NAME_id = NEW.parent_id的原因。我想知道的是如何从_id分隔TG_TABLE_NAME(触发过程)?

或者,是否有更好的方法来做到这一点?也许我做错了。

PLpgSQL有一个基本规则- PLpgSQL变量不能在嵌入式SQL中用作表名或列名。但是有一种动态的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

最新更新