Postgresql

從 UDF 返回的匿名記錄自動轉換為眾所周知的表類型

  • April 12, 2017

專有程式碼(我們無法更改)具有一堆使用者定義的類型函式:

create or replace function f() returns record as $$ ... $$

我們通過以下方式呼叫(例如):

SELECT status, log FROM f() as (status boolean, log text);

(status boolean, log text)是 table 的行類型T。是否可以在不列出屬性的情況下自動將record(或setof record返回類型)轉換為行類型?T我正在尋找的是那種:

SELECT * FROM f() as T%rowtype

有一種方法。

給定一個表t和一個f()返回與該表類型匹配的匿名記錄的函式:

CREATE TABLE t (id int, d date);

您不能只轉換匿名記錄,因為需要列定義列表

SELECT * FROM f()

引用SELECT 命令的手冊

AS如果函式已定義為返回記錄數據類型,則必須存在別名或關鍵字,後跟形式為 …的列定義列表

大膽強調我的。

因此,雖然所有這些查詢都有效:

SELECT '(1,2013-11-11)'::t;
SELECT ('(1,2013-11-11)'::t).*;
SELECT f();                      -- returning anonymous record
SELECT * FROM f() AS f(id int, d date);

這些都不做:

SELECT * FROM f();
SELECT * FROM f()::t;

後者引發異常:

錯誤:無法將類型記錄轉換為 t

您可以將SELECTwith 列定義列表包裝到@a_horse@deszo建議的VIEW或函式中。那會很好用:

CREATE OR REPLACE VIEW v1 AS
SELECT * FROM f() AS f(id int, d date);

但這不會回答你的問題:

將記錄(或記錄集返回類型)轉換為行類型T而不列出屬性?

單排解決方案

雖然強制轉換失敗,但plpgsql 中的分配有效。

CREATE OR REPLACE function f1(OUT rec t) AS
$func$
BEGIN
rec := f();   -- assignment succeeds where cast failed (!)
END
$func$ LANGUAGE plpgsql;

稱呼:

SELECT * FROM f1();

雖然您也可以使用該模式編寫集合返回函式,但我沒有找到在*SELECT*不提供列定義列表的情況下從集合返回函式…

->SQLfiddle

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