2013-08-19 10 views
6

से dblink कॉलम परिभाषा सूची निर्दिष्ट करें मैं डेटाबेस के बीच कुछ डेटा को स्थानांतरित करने के लिए dblink का उपयोग कर रहा हूं। सब कुछ बचा है और ध्वनि है, लेकिन मुझे आश्चर्य है कि क्या एक dblink क्वेरी परिणाम की कॉलम परिभाषा सूची को परिभाषित करने का एक और सुविधाजनक तरीका है। मैं कुछ इस तरह कर सकते हैं:स्थानीय मौजूदा प्रकार

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

टेबल मैं के साथ बातचीत कर रहा हूँ दोनों डेटाबेस (दूरस्थ & स्थानीय) में एक ही स्कीमा परिभाषा नहीं है। मैं की तरह कुछ के बारे में सोच रहा था:

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; 

स्तंभ परिभाषा सूची काफी लम्बी हो जाएंगी। क्या ऐसा कुछ है जिसे मैंने अनदेखा किया हो?

संपादित करें:

यह मेरे लिए एक समस्या रही है इससे पहले कि मैं के रूप में एक काम के आसपास एक छोटे से समारोह बनाई गई है।

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

यह फ़ंक्शन एक फ़ंक्शन बनाता है और उत्पन्न करता है जो 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) 
+0

मुझे आपकी मदद चाहिए। मैं जो शुरू में आपने पूछा था वह करने की कोशिश कर रहा हूं लेकिन मुझे अपना रास्ता नहीं मिल रहा है ... –

+0

मैं पूछताछ करने में सक्षम होने के लिए मध्यस्थ कार्य ('dblink_star_func') के बिना अपने भयानक कोड का संस्करण बनाने के लिए तैयार हूं 'select_remote ('dbname = ben', 'public', 'test') से चुनें * जहां डेटा = 'सफलता'; 'सीधे। क्या आप वहां मेरे प्रश्न पर एक नज़र डाल सकते हैं: http://stackoverflow.com/questions/25691511/postgresql-error-structure-of-query-does-not-match-function-result-type-using? धन्यवाद –

उत्तर

1

आप देखेंगे कि आपके प्रकार सिंक में हमेशा से रहे हैं, लेकिन यह काम करना चाहिए सुनिश्चित करने की आवश्यकता हो सकती है:

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

महत्वपूर्ण यह है कि अक्सर आप यह सुनिश्चित करना पार्सर जानता है कि आप के साथ काम कर रहे हैं कोष्ठकों की जरूरत है tuples।

उदाहरण के लिए यह मेरे लिए काम करता है:

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

लेकिन यह एक सिंटैक्स त्रुटि फेंकता है:

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

यह 'dblink' (पोस्टग्रेज़ 9.1) में काम नहीं करता है। त्रुटि को फेंकता है 'रिकॉर्डिंग' ' – ADTC

+0

@ADTC मजेदार चीज़ लौटने वाले कार्यों के लिए कॉलम परिभाषा सूची आवश्यक है क्योंकि मैं यहां आया क्योंकि' dblink' फ़ंक्शन से 'dblink_connect' में बदल गया है और अब काम नहीं कर रहा है। –

+0

नीचे @ रेमी बैरन का समाधान देखें। यह पोस्टग्रेस 9.6 में काम करता है। – kirikaza

4

कुछ इस तरह का प्रयास करें:

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) 
संबंधित मुद्दे