2011-05-21 405 views
79

我不知道,如果它的標準SQL:PostgreSQL的:INSERT INTO ...(SELECT * ...)

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

我正在尋找的是:如果TBLA和TBLB是什麼不同的數據庫服務器

不PostgreSQL給任何工具或具有任何功能,這將有助於使用INSERT query with PGresult struct

我的意思是SELECT id, time FROM tblB ...將使用PQexec返回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'); 

是否有可能創建一個準備好的聲明這件事! ! :(

+0

我不知道,如果您發佈的INSERT語法是ANSI,但它被廣泛支持(Oracle,MySQL,SQL Server,SQLite ......)。但括號不是必需的。 – 2011-05-21 16:57:50

回答

101

由於亨裏克寫下您可以使用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; 

編輯(是的,另一個):

我剛纔看到你的revised question(封閉,重複,或者只是非常相似)。

如果我的理解是正確的(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;' 
); 

我不t像嵌套的dblink,但AFAIK我不能在dblink_exec正文中引用tblB。使用LIMIT指定前20行,但我認爲你需要先使用ORDER BY子句對它們進行排序。

+1

感謝您的回覆。那麼,還有一個快速問題...'INSERT INTO tblA SELECT id,time FROM dblink('dbname = dbtest','SELECT id,time FROM tblB') AS t(id integer,time integer) WHERE time > 1000; '我可以做一個準備好的聲明嗎? – Mayank 2011-05-21 19:28:21

+0

@Mankank當然,答案已更新。 – 2011-05-21 19:44:27

9

您可以使用dblink來創建另一個數據庫解決的視圖。該數據庫可以是另一臺服務器上。

+0

感謝您的回覆。但是我沒有看到'INSERT INTO ...(SELECT FROM ...)'如何使用dblink。我需要的是'INSERT INTO ...'在dblink會話中運行到其他數據庫服務器,但是在我當前的會話中使用'(SELECT FROM ...)'。 – Mayank 2011-05-21 17:32:01

+0

您只需將tblA定義爲由dblink支持的視圖。因此插入,更新和刪除將在其他數據庫中完成。 dblink不是隻讀的。 – 2011-05-21 18:41:39

15

如果你想插入到指定的列:

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

也適用於多列 – user1575120 2016-01-27 13:55:26

1

這種表示法(第一次看到here)看起來太有用:

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