これは私のリモート機能です:
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$;
これは私のlocal関数呼び出しです。
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)
_
これは、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
_
レコードタイプを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.
_
(エラーメッセージの違いは、今回はリモート側に問題があることを示しています。)
私のバージョンで異なる鉱石の1つは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()
を使用してこの価格を支払うことは避けられません。戻り値の型に対応できる必要があるためです。