2009-11-30 36 views
10

Un poco un título vago, lo explicaré.Secuencia de comandos SQL para crear una secuencia de comandos de inserción

Estoy escribiendo una secuencia de comandos SQL para crear una declaración de inserción para cada fila de una tabla en mi base de datos, simplemente para poder volver a aplicar esa información a otra base de datos.

Aquí es lo que tengo en este momento:

SELECT 'INSERT INTO products (id,name,description) VALUES ('||ID||','''||name||''','''||description||''');' FROM products 

y funciona muy bien, dar salida a esto:

INSERT INTO products (id,name,description) VALUES (1,'Lorem','Ipsum'); 
INSERT INTO products (id,name,description) VALUES (2,'Lorem','Ipsum'); 
INSERT INTO products (id,name,description) VALUES (3,'Lorem','Ipsum'); 
INSERT INTO products (id,name,description) VALUES (4,'Lorem','Ipsum'); 

El problema es que si uno de los campos está vacía esa fila dejará de producir una secuencia de comandos de actualización, en el archivo de salida la línea está en blanco. Obviamente, como hay más de 20 campos, algunos opcionales significa que casi ninguno de mis scripts se genera.

¿Hay alguna manera de solucionar este problema?

Respuesta

5

en el caso de los campos NULL se puede hacer algo como

Select COALESCE(Name, '') from... 

la función se unen devuelve el primer valor no nulo en la lista.

Para campos realmente vacíos (nvarchar vacío por ejemplo) creo que su script anterior funcionará.

+0

Saludos Chris, esto funcionó muy bien. –

+0

Me gustaría advertirle que esto no es seguro a partir de las inyecciones de SQL. Un solo apóstrofo en una columna arruinará su SQL resultante, o podría ser explotable por un atacante para ejecutar consultas arbitrarias en su base de datos. – intgr

+2

Esto tampoco generará las mismas filas exactas. La unión como arriba terminará insertando valores de cadena vacíos donde debería estar insertando valores NULL. –

4

Utilice la función quote_nullable() nueva en PostgreSQL 8.4. Además de permitir valores NULL, que conserva sus tipos de datos y te protege de las Tablas Bobby (inyecciones SQL):

SELECT 'INSERT INTO products (id,name,description) VALUES (' || 
quote_nullable(ID) || ',' || quote_nullable(name) || ',' || 
quote_nullable(description) || ');' FROM products; 

En versiones anteriores, se obtiene el mismo comportamiento con coalesce() y quote_literal():

SELECT 'INSERT INTO products (id,name,description) VALUES (' || 
coalesce(quote_literal(ID), 'null') || ',' || 
coalesce(quote_literal(name), 'null') || ',' || 
coalesce(quote_literal(description), 'null') || ',' || 
');' FROM products; 
+0

Muchas gracias por su respuesta, pero me da un error que el quote_nullable función no existe. A pesar de esto, la solución de Chris Clarks ha funcionado. De nuevo, muchas gracias. –

+0

D'oh, 'quote_nullable()' es nuevo en PostgreSQL 8.4 – intgr

13
pg_dump -a -U user1 -t products -f products.copy database1 

y luego:

psql -U user2 -d database2 -f products.copy 

y ya está. También es más seguro y más rápido.

1

Escribí una secuencia de comandos python basada en @intgr answer para construir la instrucción select. Toma la lista de columnas separadas por comas de stdin (use -).

Quería usar sqlparse pero no pude entender cómo usar esa lib.

import fileinput 

names = ' '.join(fileinput.input()) 

ns = [x.strip() for x in names.split(',')] 
quoted = ['quote_nullable(' + x + ')' for x in ns] 
insert = "SELECT 'INSERT INTO <TABLE> (" + (', ').join(ns) + ") VALUES(' || " + (" || ',' || ").join(quoted) + " || ');' FROM <TABLE>" 
print insert 

una esencia de la secuencia de comandos está aquí: https://gist.github.com/2568047

Cuestiones relacionadas