postgresql: INSERT INTO ... (SELECT * …)

Nie jestem pewien, czy jego standardowy SQL:

 INSERT INTO tblA 
 (SELECT id, time 
    FROM tblB 
   WHERE time > 1000)  

Szukam: co jeśli tblA i tblB są na różnych serwerach DB.

Czy PostgreSql daje jakieś narzędzie lub ma jakąś funkcjonalność, która pomoże w użyciu INSERT query with PGresult struct

Mam na myśli SELECT id, time FROM tblB ... zwróci PGresult* przy użyciu PQexec. Czy jest możliwe użycie tej struktury w innej PQexec do wykonania polecenia INSERT.

EDIT:
Jeśli nie jest to możliwe, to chciałbym wyciągnąć wartości z PQresult * i Utwórz składnię wielu poleceń INSERT jak:

INSERT INTO films (code, title, did, date_prod, kind) VALUES
    ('B6717', 'Tampopo', 110, '1985-02-10', 'Comedy'),
    ('HG120', 'The Dinner Game', 140, DEFAULT, 'Comedy'); 

Czy jest możliwe stworzenie z tego przygotowanego Oświadczenia!! :(

Author: Mayank, 2011-05-21

5 answers

Jak napisał Henrik możesz użyć dblink do podłączenia zdalnej bazy danych i pobrania wyników. Na przykład:

psql dbtest
CREATE TABLE tblB (id serial, time integer);
INSERT INTO tblB (time) VALUES (5000), (2000);

psql postgres
CREATE TABLE tblA (id serial, time integer);

INSERT INTO tblA
    SELECT id, time 
    FROM dblink('dbname=dbtest', 'SELECT id, time FROM tblB')
    AS t(id integer, time integer)
    WHERE time > 1000;

TABLE tblA;
 id | time 
----+------
  1 | 5000
  2 | 2000
(2 rows)

PostgreSQL posiada pseudo-typ rekordu (tylko dla argumentu funkcji lub typu wyniku), który umożliwia odpytywanie danych z innej (nieznanej) tabeli.

Edit:

Możesz zrobić to jako przygotowane oświadczenie, jeśli chcesz i to działa, jak również:

PREPARE migrate_data (integer) AS
INSERT INTO tblA
    SELECT id, time
    FROM dblink('dbname=dbtest', 'SELECT id, time FROM tblB')
    AS t(id integer, time integer)
    WHERE time > $1;

EXECUTE migrate_data(1000);
-- DEALLOCATE migrate_data;

Edit (tak, inny):

Właśnie zobaczyłem twoje poprawione pytanie (zamknięte jako duplikat, lub po prostu bardzo podobne do tego).

Jeśli dobrze rozumiem (postgres ma tbla, a dbtest ma tblb i chcesz zdalną wstawkę z lokalnym select, a nie zdalną selekcję z lokalnym insert Jak wyżej):

psql dbtest

SELECT dblink_exec
(
    'dbname=postgres',
    'INSERT INTO tbla
        SELECT id, time
        FROM dblink
        (
            ''dbname=dbtest'',
            ''SELECT id, time FROM tblb''
        )
        AS t(id integer, time integer)
        WHERE time > 1000;'
);

Nie podoba mi się ten zagnieżdżony dblink, ale AFAIK nie mogę odwołać się do tblb w dblink_exec body. Użyj limitu, aby określić górne 20 wierszy, ale myślę, że musisz najpierw posortować je za pomocą klauzuli ORDER BY.

 114
Author: Grzegorz Szpetkowski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:33

Jeśli chcesz wstawić do kolumny:

INSERT INTO table (time)
(SELECT time FROM 
    dblink('dbname=dbtest', 'SELECT time FROM tblB') AS t(time integer) 
    WHERE time > 1000
);
 19
Author: Piotr Olaszewski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-02 13:08:06

Możesz użyć dblink aby utworzyć widok, który zostanie rozwiązany w innej bazie danych. Ta baza danych może znajdować się na innym serwerze.

 9
Author: Hendrik Brummermann,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-21 17:17:18

Ta notacja (po raz pierwszy widziana tutaj) też wygląda na przydatną:

insert into postagem (
  resumopostagem,
  textopostagem,
  dtliberacaopostagem,
  idmediaimgpostagem,
  idcatolico,
  idminisermao,
  idtipopostagem
) select
  resumominisermao,
  textominisermao,
  diaminisermao,
  idmediaimgminisermao,
  idcatolico ,
  idminisermao,
  1
from
  minisermao    
 2
Author: Sombriks,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-07 00:16:50

Oto alternatywne rozwiązanie, bez użycia dblink.

Załóżmy, że B reprezentuje źródłową bazę danych, A A reprezentuje docelową bazę danych: Następnie

  1. Kopiowanie tabeli ze źródłowego DB do docelowego DB:

    pg_dump -t <source_table> <source_db> | psql <target_db>
    
  2. Otwórz znak zachęty psql, połącz się z target_db i użyj prostego insert:

    psql
    # \c <target_db>;
    # INSERT INTO <target_table>(id, x, y) SELECT id, x, y FROM <source_table>;
    
  3. Na końcu Usuń kopię source_table , którą utworzyłeś w target_table.

    # DROP TABLE <source_table>;
    
 1
Author: Nitin Nain,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-29 05:19:49