Укажите список определений столбцов dblink из локального существующего типа

я использую dblink для перемещения определенных данных между базами данных. Все сохранено и звучит, но мне интересно, есть ли более удобный способ определить список определений столбцов результата запроса dblink. Я могу сделать что-то вроде этого:

SELECT *
FROM dblink('dbname=remote', 'select * from test')
AS t1(id integer, data text); 

таблицы, с которыми я взаимодействую, имеют одинаковое определение схемы в обеих базах данных (удаленная и локальная). Я думал о чем-то вроде:--6-->

SELECT *
FROM dblink('dbname=remote', 'select * from test')
AS t1 LIKE public.test; 

или:

SELECT *
FROM dblink('dbname=remote', 'select * from test')
AS t1::public.test;

список определений столбцов имеет тенденцию стать довольно длинным. Может, я что-то упустил?

EDIT:

как это было проблемой для меня, прежде чем я создал небольшую функцию, как обойти.

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', );
        _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 =  AND table_name = ;

        _q := format('SELECT * FROM %I.dblink(%L, %L) AS remote (%s)',
            _dblink_schema,
            _conn,
            format('SELECT * FROM %I.%I', , ),
            _cols
        );

        _func := $_func$
            CREATE OR REPLACE FUNCTION %s()
            RETURNS SETOF %I.%I
            LANGUAGE SQL
            VOLATILE STRICT
            AS $$ %s; $$
        $_func$;

        EXECUTE format(_func, _func_name, , , _q);

        RETURN _func_name;
    END;
$function$;

эта функция создает и дает функцию, которая обертывает вызов dblink. Это, конечно, не для тяжелой работы, но для удобства.Было бы неплохо, если бы оказалось, что это вовсе не обязательно.

> 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)

2 ответов


вам может потребоваться убедиться, что ваши типы всегда синхронизированы, но это должно работать:

SELECT (t1::test).* 
  FROM dblink('dbname=remote', 'select * from test') AS t1;

ключ в том, что часто вам нужны круглые скобки, чтобы убедиться, что парсер знает, что вы имеете дело с кортежами.

например, это работает для меня:

 CREATE TABLE test (id int, test bool);
 select (t1::test).* from (select 1, true) t1;

но это вызывает синтаксическую ошибку:

 select t1::test.* from (select 1, true) t1;

попробуйте что-то вроде этого :

select (rec).* from dblink('dbname=...','select myalias from foreign_table
  myalias') t1 (rec local_type)

пример (получить статистику таблиц из другой базы данных):

select (rec).* from dblink('dbname=foreignDb','select t1 from
  pg_stat_all_tables t1') t2 (rec pg_stat_all_tables)