web-dev-qa-db-ja.com

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

私はその標準SQLかどうかわからない:

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

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

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

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

編集:
不可能な場合は、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'); 

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

102
Mayank

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には record 擬似型(関数の引数または結果型の場合のみ)があります。これにより、他の(未知の)テーブルからデータをクエリすることができます。

編集する

必要に応じてそれを準備済みステートメントとして作成することもできます。それも同様に機能します。

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 bodyでtblBを参照することはできません。先頭20行を指定するにはLIMITを使用しますが、最初にORDER BY句を使用してそれらをソートする必要があると思います。

126

指定列に挿入したい場合:

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

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

9

この表記法(最初に見た ここ )も便利に見えます:

insert into postagem (
  resumopostagem,
  textopostagem,
  dtliberacaopostagem,
  idmediaimgpostagem,
  idcatolico,
  idminisermao,
  idtipopostagem
) select
  resumominisermao,
  textominisermao,
  diaminisermao,
  idmediaimgminisermao,
  idcatolico ,
  idminisermao,
  1
from
  minisermao    
8
Sombriks

これは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>;
    
1
Nitin Nain
insert into TABLENAMEA (A,B,C,D) 
select A::integer,B,C,D from TABLENAMEB
0
mahesh ingale