Insertar en ... valores ( SELECT ... FROM ... )

Estoy tratando de INSERTAR EN una tabla utilizando la entrada de otra tabla. Aunque esto es totalmente factible para muchos motores de bases de datos, siempre parece que me cuesta recordar la sintaxis correcta para el motor SQL del día (MySQL, Oracle, SQL Server, Informix y DB2).

¿Existe una sintaxis de plata procedente de un estándar SQL (por ejemplo, SQL-92) que me permita insertar los valores sin preocuparme de la base de datos subyacente?

Solución

Inténtalo:

INSERT INTO table1 ( column1 )
SELECT  col1
FROM    table2  

Este es el estándar ANSI SQL y debería funcionar en cualquier DBMS

Definitivamente funciona para:

  • Oracle
  • MS SQL Server
  • MySQL
  • Postgres
  • SQLite v3
  • Teradata
  • DB2
  • Sybase
  • Vertica
  • HSQLDB
  • H2
  • AWS RedShift
  • SAP HANA
Comentarios (0)

@Shadow_x99: Eso debería funcionar bien, y además puedes tener varias columnas y otros datos también:

INSERT INTO table1 ( column1, column2, someInt, someVarChar )
SELECT  table2.column1, table2.column2, 8, 'some string etc.'
FROM    table2
WHERE   table2.ID = 7;

Editar: Debo mencionar que sólo he utilizado esta sintaxis con Access, SQL 2000/2005/Express, MySQL, y PostgreSQL, por lo que deben ser cubiertos. Un comentarista ha señalado que funcionará con SQLite3.

Comentarios (2)

Las dos respuestas que veo funcionan bien en Informix específicamente, y son básicamente SQL estándar. Es decir, la notación:

INSERT INTO target_table[()] SELECT ... FROM ...;

funciona bien con Informix y, supongo, con todos los SGBD. (Hace 5 o más años, este es el tipo de cosas que MySQL no siempre soportaba; ahora tiene un soporte decente para este tipo de sintaxis SQL estándar y, AFAIK, funcionaría bien con esta notación). La lista de columnas es opcional, pero indica las columnas de destino en secuencia, por lo que la primera columna del resultado del SELECT irá a la primera columna listada, etc. En ausencia de la lista de columnas, la primera columna del resultado del SELECT va a la primera columna de la tabla de destino.

Lo que puede ser diferente entre sistemas es la notación utilizada para identificar las tablas en las diferentes bases de datos - el estándar no tiene nada que decir sobre las operaciones entre bases de datos (y mucho menos entre SGBD). Con Informix, puede utilizar la siguiente notación para identificar una tabla:

[dbase[@server]:][owner.]table

Es decir, puede especificar una base de datos, identificando opcionalmente el servidor que aloja esa base de datos si no está en el servidor actual, seguido de un propietario opcional, un punto y, finalmente, el nombre real de la tabla. El estándar SQL utiliza el término esquema para lo que Informix llama propietario. Así, en Informix, cualquiera de las siguientes notaciones podría identificar una tabla:

table
"owner".table
dbase:table
dbase:owner.table
dbase@server:table
dbase@server:owner.table

En general, no es necesario entrecomillar el propietario; sin embargo, si se utilizan las comillas, es necesario escribir correctamente el nombre del propietario, ya que se distingue entre mayúsculas y minúsculas. Es decir:

someone.table
"someone".table
SOMEONE.table

todos identifican la misma tabla. En el caso de Informix, existe una ligera complicación con las bases de datos MODE ANSI, donde los nombres de los propietarios se convierten generalmente en mayúsculas (informix es la excepción). Es decir, en una base de datos MODE ANSI (no se utiliza habitualmente), se podría escribir

CREATE TABLE someone.table ( ... )

y el nombre del propietario en el catálogo del sistema sería "ALGUIEN", en lugar de 'alguien'. Si encierra el nombre del propietario entre comillas dobles, actúa como un identificador delimitado. Con el SQL estándar, los identificadores delimitados pueden utilizarse en muchos lugares. Con Informix, sólo puede utilizarlos alrededor de los nombres de propietario -- en otros contextos, Informix trata las cadenas entre comillas simples y dobles como cadenas, en lugar de separar las cadenas entre comillas simples como cadenas y las cadenas entre comillas dobles como identificadores delimitados. (Por supuesto, sólo para completar, hay una variable de entorno, DELIMIDENT, que puede establecerse - a cualquier valor, pero Y es el más seguro - para indicar que las comillas dobles siempre rodean a los identificadores delimitados y las comillas simples siempre rodean a las cadenas).

Nótese que MS SQL Server se las arregla para usar [identificadores delimitados] encerrados entre corchetes. A mí me parece raro, y desde luego no forma parte del estándar SQL.

Comentarios (0)