PostgreSQL 9.3触发函数插入到具有参数化名称的表中

时间:2014-04-23 14:16:09

标签: postgresql triggers plpgsql dynamic-sql

我正在尝试动态分区Postgres中的日志条目。我有53个子表(每周有1个日志条目),并希望使用触发器将INSERT路由到子表。

我使用INSERT INTO log5 VALUES (NEW.*)运行该功能,它可以正常工作。

我使用EXECUTE语句运行该函数,但它失败了。在EXECUTE语句中,它将NEW识别为表名,而不是传递给触发器函数的变量。有关如何修复的任何想法?谢谢!

错误:

  

QUERY:插入log5 VALUES(NEW。*)
  语境:PL / pgSQL函数log_roll_test()EXECUTE语句中的第6行
  错误:缺少表“新”SQL状态的FROM子句条目: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();

1 个答案:

答案 0 :(得分:5)

CREATE FUNCTION log_roll_test()
  RETURNS trigger 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$ LANGUAGE plpgsql;

您无法在查询字符串中引用NEWNEW在函数体中可见,但不在EXECUTE环境中。最好的解决方案是传递USING子句中的值。

我还用等价的to_char(NEW.updt_ts, '"log"WW')替换了表名。 to_char()在这里更快更简单。