2011-05-21 22 views
79

no estoy seguro de si es el estándar SQL:PostgreSQL: INSERT INTO ... (SELECT * ...)

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

Lo que estoy buscando es: ¿y si TBLA y están en tblB diferentes servidores de bases de datos.

PostgreSQL da ninguna utilidad o tiene cualquier funcionalidad que le ayudará a utilizar INSERT query with PGresult struct

quiero decir SELECT id, time FROM tblB ... devolverá un PGresult* sobre el uso de PQexec. ¿Es posible usar esta estructura en otro PQexec para ejecutar un comando INSERTAR?

EDIT:
Si no es posible, entonces me gustaría ir para extraer los valores de PQresult * y crear una sintaxis de la sentencia INSERT de múltiples como:

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

¿Es posible crear una declaración preparada fuera de esto! ! :(

+0

No sé si la sintaxis INSERT informados es ANSI, pero es ampliamente compatible (Oracle, MySQL, SQL Server, SQLite ...). Pero los corchetes no son necesarios. –

Respuesta

101

Como escribió Henrik puede utilizar para conectar dblink base de datos remota a buscar resultado. Por ejemplo :

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 tiene record pseudo-tipo (sólo para el argumento de la función o el tipo de resultado), que permite consultar datos de otra tabla (desconocido)

Editar:.

Se puede hacer declaración preparada si quieres y funciona así:

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; 

Editar (sí, otro):

Acabo de ver su revised question (cerrado como duplicado, o simplemente muy similar a esto).

Si mi interpretación es correcta (Postgres tiene TBLA y dbTest tiene tblb y desea inserción remoto con local de seleccionar, no mando a distancia selecciona con páginas locales que el anterior):

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' me gusta ese nblink anidado, pero AFAIK no puedo hacer referencia a tblB en dblink_exec cuerpo. Use LIMIT para especificar las 20 filas principales, pero creo que primero debe ordenarlas usando la cláusula ORDER BY.

+1

Gracias por su respuesta. Bueno, una pregunta más rápida ... 'INSERTAR EN tblA SELECCIONAR id, tiempo DESDE dblink (' dbname = dbtest ',' SELECCIONAR id, tiempo FROM tblB ') AS t (entero de identificación, número entero de tiempo) DÓNDE hora > 1000; '¿Puedo hacer una declaración preparada de esto? – Mayank

+0

@Mayank Seguro, la respuesta está actualizada. –

9

Puede utilizar dblink para crear una vista que se resuelve en otra base de datos. Esta base de datos puede estar en otro servidor.

+0

Gracias por la respuesta.Pero no entendí cómo 'INSERT INTO ... (SELECT FROM ...) 'funcionará usando dblink. Lo que necesito es 'INSERT INTO ...' para ejecutar en la sesión de dblink a otro servidor de bases de datos, pero' (SELECT FROM ...) 'en mi sesión actual. – Mayank

+0

Usted simplemente define tblA como vista respaldada por dblink. Por lo tanto, las inserciones, actualizaciones y eliminaciones se realizarán en la otra base de datos. dblink no es de solo lectura. –

15

Si desea insertar en la columna especificar:

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

También funciona con varias columnas – user1575120

1

Esta notación (visto por primera vez here) parece útil también:

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