例如,在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