Postgresql
PostgreSQL 錯誤:遠端查詢結果行類型與指定的 FROM 子句行類型不匹配,在遠端函式呼叫上
這是我的遠端功能:
CREATE OR REPLACE FUNCTION public._test1() RETURNS record LANGUAGE plpgsql AS $function$ DECLARE rec record; BEGIN select 1,2 into rec; return rec; END $function$;
這是我的本地函式呼叫:
SELECT x.a, x.b FROM dblink('conn_str', 'select public._test1();') as x(a int ,b int);
這是拋出的錯誤:
ERROR: remote query result rowtype does not match the specified FROM clause rowtype
由於 DBLINK 要求我定義一個模式來放置函式的返回項,我如何進行呼叫以辨識
record
函式返回的類型?
要了解發生了什麼,首先檢查遙控器上正在做什麼:
SELECT _test1(); _test1 ──────── (1,2)
這確實返回一條記錄,而不是兩個整數。當
dblink()
來電報告時ERROR: remote query result rowtype does not match the specified FROM clause rowtype
這是因為您在本地將行類型定義為
x(a int, b int)
,但這與遠端上的記錄不匹配。原因是它dblink()
自己不知道(因為它本身有一個SETOF record
返回類型),因此它不能將此資訊推送到遠端。所以你需要做的是:SELECT * FROM dblink('local', 'SELECT * FROM _test1() AS x(a int, b int)') AS t(a int, b int); a │ b ───┼─── 1 │ 2
兩次指定記錄類型似乎是多餘的,但如果您省略了本地記錄類型,則會導致另一個錯誤:
SELECT * FROM dblink('local', 'SELECT * FROM _test1() AS x(a int, b int)') AS t; ERROR: a column definition list is required for functions returning "record" LINE 1: SELECT * FROM dblink('local', 'SELECT * FROM _test1() AS x(a... ^
省略遠端記錄定義:
SELECT * FROM dblink('local', 'SELECT * FROM _test1() ') AS t(a int, b int); ERROR: a column definition list is required for functions returning "record" CONTEXT: Error occurred on dblink connection named "local": could not execute query.
(錯誤資訊的差異表明這次問題出在遠端端。)
在我的版本中,有一點不同的是
SELECT * FROM _test()
. 看看當你呼叫SELECT
列表中的函式而不是FROM
子句時會發生什麼:SELECT * FROM dblink('local', 'SELECT _test1() AS x(a int, b int)') AS t(a int, b int); ERROR: syntax error at or near "(" CONTEXT: Error occurred on dblink connection named "local": could not execute query.
如果您將遠端函式創建為
RETURNS TABLE
(或者,等效地,OUT
在此處定義參數),您可以做得更好:-- on the remote CREATE FUNCTION bla() RETURNS TABLE (a int, b int) LANGUAGE SQL AS $$ SELECT 1, 2 $$; SELECT * FROM dblink('local', 'SELECT * FROM bla() ') AS t(a int, b int); a │ b ───┼─── 1 │ 2
該
record
類型被設計為靈活,但它是有代價的。但是,您無法避免用 支付這個價格dblink()
,因為它必須能夠適應任何返回類型。