我正在尝试动态分区 Postgres 中的日志条目。我有 53 个子表(每周 1 个用于日志条目),并且想使用触发器将 INSERT 路由到子表。
我使用 INSERT INTO log5 VALUES (NEW.*)
运行该函数,它有效。
我改为使用 EXECUTE
语句运行该函数,但它失败了。在 EXECUTE
语句中,它将 NEW
识别为表名,而不是传递给触发器函数的变量。关于如何修复的任何想法?谢谢!
错误:
QUERY: INSERT INTO log5 VALUES (NEW.*)
CONTEXT: PL/pgSQL function log_roll_test() line 6 at EXECUTE statement
ERROR: missing FROM-clause entry for table "new" SQL state: 42P01
我的函数:
CREATE FUNCTION log_roll_test() RETURNS trigger AS $body$
DECLARE t text;
BEGIN
t := 'log' || extract(week FROM NEW.updt_ts); --child table name
--INSERT INTO log5 VALUES (NEW.*);
EXECUTE format('INSERT INTO %I VALUES (NEW.*);', t);
RETURN NULL;
END;
$body$ LANGUAGE plpgsql;
我的触发器:
CREATE TRIGGER log_roll_test
BEFORE INSERT ON log FOR EACH ROW
EXECUTE PROCEDURE log_roll_test();
最佳答案
CREATE FUNCTION log_roll_test()
RETURNS trigger
LANGUAGE plpgsql AS
$func$
BEGIN
EXECUTE format('INSERT INTO %I SELECT ($1).*' -- !
, to_char(NEW.updt_ts, '"log"WW')) -- child table name
USING NEW; -- !
RETURN NULL;
END
$func$;
您不能在查询字符串中引用 NEW
。 NEW
在函数体中可见,但在 EXECUTE
环境中不可见。最好的解决方案是在 USING
子句中传递值。
我还用等效的 to_char(NEW.updt_ts, '"log"WW')
替换了表名。 to_char()
在这里更快更简单。
关于PostgreSQL 9.3 触发器函数插入到具有参数化名称的表中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23247105/