Geben Sie die Definitionsliste für dblink-Spalten von einem lokal vorhandenen Typ an
Ich benutze dblink, um bestimmte Daten zwischen Datenbanken zu verschieben. Alles ist sicher und solide, aber ich frage mich, ob es eine bequemere Möglichkeit gibt, die Spaltendefinitionsliste eines dblink-Abfrageergebnisses zu definieren. Ich kann so etwas machen:
SELECT *
FROM dblink('dbname=remote', 'select * from test')
AS t1(id integer, data text);
Die Tabellen, mit denen ich interagiere, haben dieselbe Schemadefinition in beiden Datenbanken (remote und lokal). Ich dachte an etwas wie:
SELECT *
FROM dblink('dbname=remote', 'select * from test')
AS t1 LIKE public.test;
Oder:
SELECT *
FROM dblink('dbname=remote', 'select * from test')
AS t1::public.test;
Die Spaltendefinitionsliste wird in der Regel ziemlich lang. Gibt es etwas, das ich übersehen habe?
BEARBEITEN:
Da dies ein Problem für mich war, bevor ich eine kleine Funktion als Workaround erstellt habe.
CREATE OR REPLACE FUNCTION dblink_star_func(_conn text, _schema_name text, _table_name text)
RETURNS text
LANGUAGE PLPGSQL
VOLATILE STRICT
AS $function$
DECLARE
_dblink_schema text;
_cols text;
_q text;
_func_name text := format('star_%s', $3);
_func text;
BEGIN
SELECT nspname INTO _dblink_schema
FROM pg_namespace n, pg_extension e
WHERE e.extname = 'dblink' AND e.extnamespace = n.oid;
SELECT array_to_string(array_agg(column_name || ' ' || udt_name), ', ') INTO _cols
FROM information_schema.columns
WHERE table_schema = $2 AND table_name = $3;
_q := format('SELECT * FROM %I.dblink(%L, %L) AS remote (%s)',
_dblink_schema,
_conn,
format('SELECT * FROM %I.%I', $2, $3),
_cols
);
_func := $_func$
CREATE OR REPLACE FUNCTION %s()
RETURNS SETOF %I.%I
LANGUAGE SQL
VOLATILE STRICT
AS $ %s; $
$_func$;
EXECUTE format(_func, _func_name, $2, $3, _q);
RETURN _func_name;
END;
$function$;
Diese Funktion erstellt und liefert eine Funktion, die den dblink-Aufruf umschließt. Es ist sicherlich nicht für schweres Heben gedacht, aber für Bequemlichkeit. Es wäre schön, wenn sich herausstellen würde, dass es überhaupt nicht notwendig ist.
> select dblink_star_func('dbname=ben', 'public', 'test');
┌──────────────────┐
│ dblink_star_func │
├──────────────────┤
│ star_test │
└──────────────────┘
(1 row)
> select * from star_test() where data = 'success';
┌────┬─────────┐
│ id │ data │
├────┼─────────┤
│ 1 │ success │
└────┴─────────┘
(1 row)