例如,在Perl中,您可以像这样分隔变量:
${foo}_bar
我在PostgreSQL中有一个从here借来的触发器,我试图通用它来处理多个表。这是我的代码:
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(触发程序)?
或者,有更好的方法吗?也许我只是错了。
答案 0 :(得分:1)
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