167

我不确定它是否是标准 SQL:

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

我正在寻找的是:如果 tblA 和 tblB 在不同的 DB Servers 中会怎样

PostgreSql 是否提供任何实用程序或具有任何有助于使用的功能INSERT query with PGresult struct

我的意思是会在 using 上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

As Henrik wrote you can use dblink to connect remote database and fetch result. For example:

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 has record pseudo-type (only for function's argument or result type), which allows you query data from another (unknown) table.

Edit:

You can make it as prepared statement if you want and it works as well:

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 (yeah, another):

I just saw your revised question (closed as duplicate, or just very similar to this).

If my understanding is correct (postgres has tbla and dbtest has tblb and you want remote insert with local select, not remote select with local insert as above):

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

I don't like that nested dblink, but AFAIK I can't reference to tblB in dblink_exec body. Use LIMIT to specify top 20 rows, but I think you need to sort them using ORDER BY clause first.

于 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

如果您正在寻找PERFORMANCE,请在 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. 将表从源数据库复制到目标数据库:

    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 回答