197 votes

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

Je ne suis pas sûr si son standard SQL:

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

Ce que je cherche est: que faire si tblA et tblB sont dans les différents Serveurs de DB.

PostgreSql donne aucune utilité ou a toutes les fonctionnalités qui vous aideront à utiliser INSERT query with PGresult struct

Je veux dire, SELECT id, time FROM tblB ... retournera PGresult* sur l'utilisation de l' PQexec. Est-il possible d'utiliser cette structure dans un autre PQexec d'exécuter une commande INSERT.

EDIT:
Si pas possible, alors je pencherais pour extraire les valeurs de PQresult*, et de créer un multiple INSÉRER syntaxe de l'instruction comme:

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

Est-il possible de créer une déclaration préparée à l'avance!! :(

218voto

Grzegorz Szpetkowski Points 10225

Comme Henrik écrit, vous pouvez utiliser dblink pour se connecter à distance de la base de données et extraire les résultats. Par exemple:

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 dispose d' enregistrement pseudo-type (uniquement pour la fonction de l'argument ou le type de résultat), ce qui vous permet de requête de données à partir d'un autre (inconnu) de la table.

Edit:

Vous pouvez le faire comme déclaration préparée à l'avance si vous le souhaitez et cela fonctionne ainsi:

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 (oui, un autre):

Je viens de voir votre question ainsi modifiée (fermé comme un double, ou tout simplement très similaire à cela).

Si ma compréhension est correcte (postgres a tbla et dbtest a tblb et que vous voulez à distance avec insert local sélectionnez, pas de télécommande sélectionnez avec local insérer comme ci-dessus):

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

Je n'aime pas imbriquée dblink, mais autant que je sache, je ne peux pas référence à tblB dans dblink_exec corps. LIMITE d'utilisation pour spécifier le top 20 lignes, mais je pense que vous avez besoin de les trier à l'aide de la COMMANDE PAR l'alinéa premier.

10voto

Vous pouvez utiliser dblink pour créer une vue résolue dans une autre base de données. Cette base de données peut être sur un autre serveur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X