將記錄變數中的值插入子類表
我的目標是創建一個儲存過程來建構 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 沒有儲存過程。(最顯著的區別:函式總是在單個事務範圍內執行。)