Postgresql

PostgreSQL 錯誤:遠端查詢結果行類型與指定的 FROM 子句行類型不匹配,在遠端函式呼叫上

  • October 28, 2020

這是我的遠端功能:

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(),因為它必須能夠適應任何返回類型。

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