postgresql – 将记录变量中的值插入表中

我正在开发一个带有两个参数的用户定义函数:

create or replace function gesio(
    events_table_in regclass,  
    events_table_out regclass)
returns void as $$... $$

events_table_in和events_table_out具有完全相同的架构.

简单地解释一下,我循环遍历events_table_in的记录,操纵记录并希望以下列方式将操纵的记录追加(插入)到events_table_out:

OPEN recCurs FOR execute 
format('SELECT * FROM %s order by session_id, event_time', event_table_in);

LOOP
    FETCH recCurs into rec;
    if not found then
      exit;
    end if;

    -- 1. do something with rec

    -- 2. insert the rec into events_table_out

end loop;

如何将rec保存到events_table_out中?

最佳答案
只有PL / pgSQL有一个解决方案.简单而优雅.但是很高级的东西.
需要Postgres 9.0或更高版本(可能为旧版本提供解决方法).

CREATE OR REPLACE FUNCTION gesio(_tbl_in anyelement, _tbl_out regclass)
  RETURNS void AS
$func$
BEGIN

FOR _tbl_in IN EXECUTE
   format('SELECT * FROM %s', pg_typeof(_tbl_in))
LOOP
   -- do something with record

   EXECUTE format('INSERT INTO %s SELECT $1.*', _tbl_out)
   USING _tbl_in;
END LOOP;

END
$func$ LANGUAGE plpgsql;

打电话(重要!):

SELECT gesio(NULL::t, 't1');

t和t1是具有相同模式的表.

请注意,只有在函数体中需要计算值或数据类型时才需要多态参数(anyelement).另外,您可以简化,如后面的答案所示:

> Insert values from a record variable into a subclass table

主要成分

> Implicit cursor of a FOR loop而不是显式游标.这通常是可取的.
> Polymorphic types
> Object identifier types
> Dynamic SQL in plpgsql
> VALUES can take a row type directly.

要克服的障碍是函数内部的变量不能被定义为多态类型anyelement(尚). This related answer on SO解释了解决方案.为旧版本提供解决方法.

我正在处理类型为t的NULL值,它有三个用途:

>提供表名.
>提供表格类型.
>作为循环变量.

第一个参数的值被丢弃.使用NULL.

考虑this related answer on SO with more details.最有趣的部分是最后一章各种完整的表格类型.

SQL Fiddle demo.

如果您的计算不太复杂,您可以使用单个动态SQL语句替换循环,这通常更快.

转载注明原文:postgresql – 将记录变量中的值插入表中 - 代码日志