Inserire in ... valori ( SELECT ... FROM ... )

Sto cercando di INSERT INTO una tabella usando l'input di un'altra tabella. Anche se questo è del tutto fattibile per molti motori di database, sembra che io faccia sempre fatica a ricordare la sintassi corretta per il motore SQL del giorno (MySQL, Oracle, SQL Server, Informix, e DB2).

C'è una sintassi silver-bullet proveniente da uno standard SQL (per esempio, SQL-92) che mi permetterebbe di inserire i valori senza preoccuparmi del database sottostante?

Soluzione

Prova:

INSERT INTO table1 ( column1 )
SELECT  col1
FROM    table2  

Questo è ANSI SQL standard e dovrebbe funzionare su qualsiasi DBMS

Funziona sicuramente per:

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

@Shadow_x99: Dovrebbe funzionare bene, e puoi anche avere più colonne e altri dati:

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

Edit: Devo dire che ho usato questa sintassi solo con Access, SQL 2000/2005/Express, MySQL e PostgreSQL, quindi questi dovrebbero essere coperti. Un commentatore ha fatto notare che funzionerà con SQLite3.

Commentari (2)

Entrambe le risposte che vedo funzionano bene in Informix in particolare, e sono fondamentalmente SQL standard. Cioè la notazione:

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

funziona bene con Informix e, mi aspetto, con tutti i DBMS. (Una volta, 5 o più anni fa, questo è il genere di cose che MySQL non sempre supportava; ora ha un supporto decente per questo tipo di sintassi SQL standard e, AFAIK, funzionerebbe bene con questa notazione). L'elenco delle colonne è opzionale ma indica le colonne di destinazione in sequenza, quindi la prima colonna del risultato della SELECT andrà nella prima colonna elencata, ecc. In assenza dell'elenco di colonne, la prima colonna del risultato della SELECT va nella prima colonna della tabella di destinazione.

Ciò che può essere diverso tra i sistemi è la notazione usata per identificare le tabelle nei diversi database - lo standard non ha nulla da dire sulle operazioni inter-database (per non parlare delle operazioni inter-DBMS). Con Informix, puoi usare la seguente notazione per identificare una tabella:

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

Cioè, si può specificare un database, opzionalmente identificando il server che ospita quel database se non è nel server corrente, seguito da un proprietario opzionale, un punto, e infine il nome effettivo della tabella. Lo standard SQL usa il termine schema per quello che Informix chiama il proprietario. Così, in Informix, una qualsiasi delle seguenti notazioni potrebbe identificare una tabella:

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

Il proprietario in generale non ha bisogno di essere virgolettato; tuttavia, se usate le virgolette, dovete far scrivere correttamente il nome del proprietario - diventa case-sensitive. Cioè:

someone.table
"someone".table
SOMEONE.table

tutti identificano la stessa tabella. Con Informix, c'è una leggera complicazione con i database MODE ANSI, dove i nomi dei proprietari sono generalmente convertiti in maiuscolo (informix è l'eccezione). Cioè, in un database MODE ANSI (non comunemente usato), si potrebbe scrivere:

CREATE TABLE someone.table ( ... )

e il nome del proprietario nel catalogo del sistema sarebbe "SOMEONE", piuttosto che 'qualcuno'. Se si racchiude il nome del proprietario tra doppi apici, si comporta come un identificatore delimitato. Con SQL standard, gli identificatori delimitati possono essere usati in molti posti. Con Informix, potete usarli solo intorno ai nomi dei proprietari -- in altri contesti, Informix tratta sia le stringhe tra apici singoli che quelle tra doppi apici come stringhe, piuttosto che separare le stringhe tra apici singoli come stringhe e quelle tra doppi apici come identificatori delimitati. (Naturalmente, solo per completezza, c'è una variabile d'ambiente, DELIMIDENT, che può essere impostata - a qualsiasi valore, ma Y è il più sicuro - per indicare che i doppi apici circondano sempre gli identificatori delimitati e i singoli apici circondano sempre le stringhe).

Si noti che MS SQL Server riesce ad usare [identificatori delimitati] racchiusi tra parentesi quadre. Mi sembra strano, e certamente non fa parte dello standard SQL.

Commentari (0)