Postgresql

將記錄變數中的值插入表中

  • November 13, 2020

我正在開發一個帶有兩個參數的使用者定義函式:

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

events_table_inevents_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;

我怎樣才能保存recevents_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,僅當您需要它的值或數據類型用於函式體中的計算時,才需要多態參數 ( )。否則,您可以像後面的答案中展示的那樣簡化:

主要成分

要克服的一個障礙是函式內部的變數不能定義為多態類型anyelement(還)。這個關於 SO 的相關答案解釋了解決方案。也為舊版本提供了解決方法。

我正在送出一個NULLtype 的值t,它有三個目的:

  • 提供表名。
  • 提供表格類型。
  • 作為循環變數。

第一個參數的值被**丟棄。使用NULL.

考慮更多關於 SO 的相關答案。最有趣的部分是最後一章各種完整的表格類型

SQL Fiddle 展示。

如果您的計算不是太複雜,您可以將循環替換為單個動態 SQL 語句,這通常更快。

引用自:https://dba.stackexchange.com/questions/52826