2013-08-19 9 views
6

Używam dblinka, aby przenieść określone dane między bazami danych. Wszystko jest zapisane i dźwiękowe, ale zastanawiam się, czy istnieje wygodniejszy sposób definiowania listy definicji kolumny wyniku kwerendy dblink. Mogę zrobić coś takiego:Określanie listy definicji kolumny dblink z lokalnego istniejącego typu

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

Tabele mam oddziałujące ze mają taką samą definicję schematu w obu bazach danych (Remote & lokalny). Myślałem o czymś takim:

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

czyli lista definicja

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

Kolumna tendencję do stawania się dość długo. Czy jest coś, co mogłem przeoczyć?

EDIT:

Jak to było dla mnie problemem, zanim stworzył małą funkcję jak obejście.

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$; 

Ta funkcja tworzy i daje funkcję, która opakowuje wywołanie dblink. Z pewnością nie jest przeznaczony do podnoszenia ciężarów, ale do wygody. Byłoby miło, gdyby okazało się, że wcale nie jest konieczne.

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

Potrzebuję twojej pomocy. Próbuję zrobić to, co początkowo zadawałeś, ale nie mogę znaleźć swojej drogi ... –

+0

Mam problem z utworzeniem wersji twojego niesamowitego kodu bez funkcji pośrednika ('dblink_star_func'), aby móc wyszukiwać 'select * from select_remote ('dbname = ben', 'public', 'test') gdzie dane = 'sukces';' od razu. Czy możesz rzucić okiem na moje pytanie: http://stackoverflow.com/questions/25691511/postgresql-error-structure-of-query-does-not-match-function-result-type-using? Dzięki –

Odpowiedz

1

może być konieczne, aby upewnić się, że typy są zawsze zsynchronizowane, ale to powinno działać:

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

Kluczem jest to, że często trzeba nawiasy, aby upewnić się, że parser wie, że mamy do czynienia z krotki.

Na przykład działa to dla mnie:

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

Ale to generuje błąd składni:

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

Nie działa w 'dblink' (Postgres 9.1). Zgłasza błąd 'lista definicji kolumn jest wymagana dla funkcji zwracających" rekord "' – ADTC

+0

@ADTC Zabawna rzecz, którą tu przyszedłem, ponieważ zmieniono z funkcji 'dblink' na' dblink_connect', a teraz nie działa. –

+0

Zobacz poniżej rozwiązanie Barona @ Rémy'ego. Działa to w Postgresie 9.6. – kirikaza

4

spróbować czegoś takiego:

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

Przykład (dostać statystyk tabel z inna baza danych):

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