167

その標準SQLかどうかはわかりません:

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

私が探しているのは、tblAとtblBが異なるDBサーバーにある場合はどうなるかということです。

PostgreSqlはユーティリティを提供しますか、または使用するのに役立つ機能を持っていますかINSERT query with PGresult struct

つまり、を使用してをSELECT id, time FROM tblB ...返します。この構造体を別の構造体で使用してINSERTコマンドを実行する ことは可能ですか?PGresult*PQexecPQexec

編集:
不可能な場合は、PQresult *から値を抽出し、次のような複数のINSERTステートメント構文を作成します。

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

これからプリペアドステートメントを作成することは可能ですか?:(

4

7 に答える 7

188

Henrikが書いたように、dblinkを使用してリモートデータベースに接続し、結果を取得できます。例えば:

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にはレコード疑似型(関数の引数または結果型のみ)があり、別の(不明な)テーブルからデータをクエリできます。

編集:

必要に応じて、プリペアドステートメントとして作成できます。これも機能します。

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;

編集(ええ、別の):

私はあなたの改訂された質問を見ました(重複として閉じられたか、これに非常に似ています)。

私の理解が正しければ(postgresにはtblaがあり、dbtestにはtblbがあり、上記のようにローカル挿入を使用したリモート選択ではなく、ローカル選択を使用したリモート挿入が必要です):

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

ネストされたdblinkは好きではありませんが、dblink_exec本体でtblBを参照することはできません。LIMITを使用して上位20行を指定しますが、最初にORDERBY句を使用してそれらを並べ替える必要があると思います。

于 2011-05-21T17:53:39.727 に答える
50

指定列に挿入する場合:

INSERT INTO table (time)
(SELECT time FROM 
    dblink('dbname=dbtest', 'SELECT time FROM tblB') AS t(time integer) 
    WHERE time > 1000
);
于 2015-02-02T13:08:06.933 に答える
16

この表記(最初にここで見られる)も便利に見えます:

insert into postagem (
  resumopostagem,
  textopostagem,
  dtliberacaopostagem,
  idmediaimgpostagem,
  idcatolico,
  idminisermao,
  idtipopostagem
) select
  resumominisermao,
  textominisermao,
  diaminisermao,
  idmediaimgminisermao,
  idcatolico ,
  idminisermao,
  1
from
  minisermao    
于 2018-02-07T00:16:50.783 に答える
8

dblinkを使用して、別のデータベースで解決されるビューを作成できます。このデータベースは別のサーバー上にある可能性があります。

于 2011-05-21T17:17:18.280 に答える
5
insert into TABLENAMEA (A,B,C,D) 
select A::integer,B,C,D from TABLENAMEB
于 2018-12-10T12:43:39.363 に答える
0

パフォーマンスを探している場合は、dbリンククエリ内のwhere条件を指定してください。それ以外の場合は、外部テーブルからすべてのデータをフェッチし、where条件を適用します。

INSERT INTO tblA (id,time) 
SELECT id, time FROM  dblink('dbname=dbname port=5432 host=10.10.90.190 user=postgresuser password=pass123', 
'select id, time from tblB  where time>'''||1000||'''')
AS t1(id integer, time integer)  
于 2021-01-05T05:55:21.610 に答える
-1

を使用しない別の解決策を次に示しdblinkます。

Bがソースデータベースを表し、Aがターゲットデータベースを表すとします。次に、

  1. ソースDBからターゲットDBにテーブルをコピーします。

    pg_dump -t <source_table> <source_db> | psql <target_db>
    
  2. psqlプロンプトを開き、target_dbに接続して、単純なものを使用しますinsert

    psql
    # \c <target_db>;
    # INSERT INTO <target_table>(id, x, y) SELECT id, x, y FROM <source_table>;
    
  3. 最後に、target_tableで作成したsource_tableのコピーを削除します。

    # DROP TABLE <source_table>;
    
于 2018-07-26T12:19:24.190 に答える