Postgresql

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

  • February 14, 2017

我的目標是創建一個儲存過程來建構 a _tbl_out,它是 a 的子類_tbl_in。我正在關注這個問題的結果,但要使其正常工作,表需要具有相同的架構。我希望 output_table 具有相同的架構加上一些額外的計算列。

我是否必須使用比連結的解決方案更不優雅的解決方案?還是有一種解決方案可以在將列_tbl_in插入到子類之前將其附加到記錄上_tbl_out

以下是上一個解決方案的程式碼供參考:

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是具有相同架構的表。

你的目標是…

建構 a 的儲存過程,_tbl_out它是 a 的子類_tbl_in

並且通過“子類”,您的意思是_tbl_out.

因此,該函式應採用兩個表名並將內容從第一個複製到第二個 - 加上一個或多個附加(計算?)列。關於表定義,我們唯一知道的是:第二個有額外的懸空列。

您只需要一個多態參數 ( ANYELEMENT) 來傳入或返回動態類型的**值- 或者至少使用函式體中類型的變數。您展示的內容不返回任何內容 ( ),也不需要輸入類型。您只使用從輸入參數派生的表名和參數本身作為輔助變數 - 在簡化函式後就消失了。RETURNS void

除非您根據多態參數的類型或值進行計算,否則兩個regclass參數和一個動態語句可以完成這項工作,而且速度也快得多。(甚至只有兩個text參數傳遞有效的表名,但regclass更可靠):

CREATE OR REPLACE FUNCTION pg_temp.gesio(_tbl_in regclass, _tbl_out regclass)
 RETURNS void AS
$func$
BEGIN
  EXECUTE format($$
     INSERT INTO %s       -- *no* target column list
     SELECT *
          , 'some value'  -- AS computed_column1  -- column alias only for documentation
         -- more ?
     FROM   %s$$$         -- ORDER BY ???
   , _tbl_out, _tbl_in);
END
$func$  LANGUAGE plpgsql;

我在您引用的舊答案中添加了一條註釋,但不夠清楚:

大桌子的性能

導致成本的一個主要因素是必須為此表單維護的預寫日誌 (WAL)。有一些方法可以完全避免這種情況並使其速度大大加快:在事務中寫入一個全新的表,因此在送出之前它對世界其他地方是不可見的。細節:

旁白:它是一個函式,而不是一個儲存過程。嚴格來說,Postgres 沒有儲存過程。(最顯著的區別:函式總是在單個事務範圍內執行。)

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