加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

postgresql – 在PL / pgsql中使用EXECUTE从通用触发器插入NEW.*

发布时间:2020-12-13 16:25:50 所属栏目:百科 来源:网络整理
导读:我有一些表使用Postgres“分区”功能.我想在每个表上定义一个常见的BEFORE INSERT OF ROW触发器,这将在1)动态创建分区,如果插入发生在父表上,2)重新执行对分区的插入. 就像是: CREATE OR REPLACE FUNCTION partition_insert_redirect( )RETURNS trigger AS
我有一些表使用Postgres“分区”功能.我想在每个表上定义一个常见的BEFORE INSERT OF ROW触发器,这将在1)动态创建分区,如果插入发生在父表上,2)重新执行对分区的插入.

就像是:

CREATE OR REPLACE FUNCTION partition_insert_redirect( )
RETURNS trigger AS $BODY$
BEGIN
  ... create the new partition and set up the redirect Rules ...

  /* Redo the INSERT dynamically.  The new RULE will redirect it to the child table */
  EXECUTE 'INSERT INTO ' || quote_ident(TG_TABLE_SCHEMA) || '.' || quote_ident(TG_TABLE_NAME) ||
          ' SELECT NEW.*'
END

但是,“NEW”记录在EXECUTE SQL中是不可见的.我该如何尽可能简单地进行这项工作?

作为替代,我可以以某种方式迭代NEW记录中的字段吗?

我想过使用临时表:

EXECUTE 'CREATE TEMPORARY TABLE new_row (LIKE ' ||
        quote_ident(TG_TABLE_SCHEMA) || '.' || quote_ident(TG_TABLE_NAME) ||
        ') ON COMMIT DROP';

INSERT INTO new_row SELECT NEW.*;

EXECUTE 'INSERT INTO ' || quote_ident(TG_TABLE_SCHEMA) || '.' || quote_ident(TG_TABLE_NAME) ||
       ' SELECT * FROM new_row';
DROP TABLE new_row;

但是由于缓存引用临时表:Why do I get “relation with OID ##### does not exist” errors when accessing temporary tables in PL/PgSQL functions?,这也不起作用

我使用Postgres 8.2,我不能改变任何其他版本.

编辑:
正如@alvherre指出的那样,这可以在Postgres 8.4中使用EXECUTE … USING语法完成.见http://wiki.postgresql.org/wiki/PL/pgSQL_Dynamic_Triggers的一个例子

您可以使用EXECUTE USING将其传递给它.你的例子是
EXECUTE 'INSERT INTO ' || TG_RELID || '::regclass SELECT $1' USING NEW;

(注意,我使用TG_RELID转换为regclass,而不是使用TG_TABLE_SCHEMA和TABLE_NAME,因为它更容易使用,如果非标准,但是,然后,plpgsql是非标准的.)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读