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

May*_*ank 106 sql postgresql dblink insert

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

 INSERT INTO tblA 
 (SELECT id, time 
    FROM tblB 
   WHERE time > 1000)  
Run Code Online (Sandbox Code Playgroud)

我正在寻找的是:如果tblA和tblB在不同的DB服务器中,该怎么办

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

我的意思是SELECT id, time FROM tblB ...将返回PGresult*使用PQexec.是否可以在另一个结构中使用此结构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'); 
Run Code Online (Sandbox Code Playgroud)

是否有可能创建一个准备好的声明!:(

Grz*_*ski 132

正如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)
Run Code Online (Sandbox Code Playgroud)

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;
Run Code Online (Sandbox Code Playgroud)

编辑(是的,另一个):

我刚刚看到你修改过的问题(关闭为重复,或者与此非常相似).

如果我的理解是正确的(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;'
);
Run Code Online (Sandbox Code Playgroud)

我不喜欢嵌套的dblink,但AFAIK我不能在dblink_exec体中引用tblB.使用LIMIT指定前20行,但我认为您需要先使用ORDER BY子句对它们进行排序.


Pio*_*ski 24

如果要插入指定列:

INSERT INTO table (time)
(SELECT time FROM 
    dblink('dbname=dbtest', 'SELECT time FROM tblB') AS t(time integer) 
    WHERE time > 1000
);
Run Code Online (Sandbox Code Playgroud)


Hen*_*ann 9

您可以使用dblink创建在另一个数据库中解析的视图.此数据库可能位于另一台服务器上.


Som*_*iks 8

这种表示法(在这里首次出现)看起来也很有用:

insert into postagem (
  resumopostagem,
  textopostagem,
  dtliberacaopostagem,
  idmediaimgpostagem,
  idcatolico,
  idminisermao,
  idtipopostagem
) select
  resumominisermao,
  textominisermao,
  diaminisermao,
  idmediaimgminisermao,
  idcatolico ,
  idminisermao,
  1
from
  minisermao    
Run Code Online (Sandbox Code Playgroud)

  • 这仅在表位于同一数据库中时才有效。问题是关于从 ** 不同数据库中的表** 复制数据。 (4认同)

小智 7

insert into TABLENAMEA (A,B,C,D) 
select A::integer,B,C,D from TABLENAMEB
Run Code Online (Sandbox Code Playgroud)


REM*_*ITH 5

如果您正在寻找PERFORMANCE,请在数据库链接查询中给出 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)  
Run Code Online (Sandbox Code Playgroud)