viste - popolazione tabella sql




Inserisci in... valori(SELEZIONA... DA...) (15)

Sto cercando di INSERT INTO una tabella usando l'input da un'altra tabella. Sebbene questo sia interamente fattibile per molti motori di database, mi sembra sempre difficile ricordare la sintassi corretta per il motore SQL del giorno ( MySQL , Oracle , SQL Server , Informix e DB2 ).

Esiste una sintassi silver-bullet derivante da uno standard SQL (ad esempio, SQL-92 ) che consenta di inserire i valori senza preoccuparmi del database sottostante?


@ Shadow_x99 : dovrebbe funzionare Shadow_x99 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;

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


Basta usare le parentesi per la clausola SELECT in INSERT. Ad esempio in questo modo:

INSERT INTO Table1 (col1, col2, your_desired_value_from_select_clause, col3)
VALUES (
   'col1_value', 
   'col2_value',
   (SELECT col_Table2 FROM Table2 WHERE IdTable2 = 'your_satisfied_value_for_col_Table2_selected'),
   'col3_value'
);

Ecco un altro esempio in cui la fonte viene utilizzata utilizzando più di una tabella:

INSERT INTO cesc_pf_stmt_ext_wrk( 
  PF_EMP_CODE    ,
  PF_DEPT_CODE   ,
  PF_SEC_CODE    ,
  PF_PROL_NO     ,
  PF_FM_SEQ      ,
  PF_SEQ_NO      ,
  PF_SEP_TAG     ,
  PF_SOURCE) 
SELECT
  PFl_EMP_CODE    ,
  PFl_DEPT_CODE   ,
  PFl_SEC         ,
  PFl_PROL_NO     ,
  PF_FM_SEQ       ,
  PF_SEQ_NO       ,
  PFl_SEP_TAG     ,
  PF_SOURCE
 FROM cesc_pf_stmt_ext,
      cesc_pfl_emp_master
 WHERE pfl_sep_tag LIKE '0'
   AND pfl_emp_code=pf_emp_code(+);

COMMIT;

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

INSERT INTO target_table[(<column-list>)] SELECT ... FROM ...;

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

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

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

Cioè, puoi specificare un database, opzionalmente identificando il server che ospita quel database se non si trova nel server corrente, seguito da un proprietario opzionale, punto e infine il nome effettivo della tabella. Lo standard SQL utilizza lo schema dei termini per ciò che Informix chiama il proprietario. Pertanto, in Informix, una qualsiasi delle seguenti notazioni potrebbe identificare una tabella:

table
"owner".table
dbase:table
dbase:owner.table
[email protected]:table
[email protected]:owner.table

Il proprietario in generale non ha bisogno di essere quotato; tuttavia, se si utilizzano le virgolette, è necessario ottenere il nome del proprietario digitato correttamente - diventa case-sensitive. Questo è:

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 lettere maiuscole (informix è l'eccezione). Cioè, in un database MODE ANSI (non comunemente usato), potresti scrivere:

CREATE TABLE someone.table ( ... )

e il nome del proprietario nel catalogo di sistema sarebbe "QUALCUNO", piuttosto che "qualcuno". Se si racchiude il nome del proprietario tra virgolette, si comporta come un identificatore delimitato. Con SQL standard, gli identificatori delimitati possono essere utilizzati in molti posti. Con Informix, è possibile utilizzarli solo attorno ai nomi dei proprietari - in altri contesti, Informix tratta sia stringhe con quotatura singola che doppia citazione come stringhe, anziché separare stringhe con quotatura singola come stringhe e stringhe con doppi apici come identificatori delimitati. (Naturalmente, solo per completezza, c'è una variabile d'ambiente, DELIMIDENT, che può essere impostata - su qualsiasi valore, ma Y è la più sicura - per indicare che le virgolette sempre circondano gli identificatori delimitati e le virgolette sempre circondano le stringhe.)

Si noti che MS SQL Server riesce a utilizzare [identificatori delimitati] racchiusi tra parentesi quadre. Sembra strano per me, e certamente non fa parte dello standard SQL.


In realtà io preferisco quanto segue in SQL Server 2008:

SELECT Table1.Column1, Table1.Column2, Table2.Column1, Table2.Column2, 'Some String' AS SomeString, 8 AS SomeInt
INTO Table3
FROM Table1 INNER JOIN Table2 ON Table1.Column1 = Table2.Column3

Elimina il passo dell'aggiunta dell'insieme Insert () e basta selezionare quali valori vanno nella tabella.


Inserimento semplice quando è nota la sequenza della colonna della tabella:

    Insert into Table1
    values(1,2,...)

Colonna di inserimento semplice:

    Insert into Table1(col2,col4)
    values(1,2)

Inserimento di massa quando il numero di colonne selezionate di una tabella (# table2) è uguale alla tabella di inserimento (Tabella 1)

    Insert into Table1 {Column sequence}
    Select * -- column sequence should be same.
       from #table2

Inserimento di massa quando si desidera inserire solo nella colonna desiderata di una tabella (tabella1):

    Insert into Table1 (Column1,Column2 ....Desired Column from Table1)  
    Select Column1,Column2..desired column from #table2
       from #table2

La maggior parte dei database segue la sintassi di base,

INSERT INTO TABLE_NAME
SELECT COL1, COL2 ...
FROM TABLE_YOU_NEED_TO_TAKE_FROM
;

Ogni database che ho usato segue questa sintassi, cioè DB2 , SQL Server , MY SQL , PostgresQL


Per Microsoft SQL Server, consiglierò di imparare a interpretare SYNTAX fornito su MSDN. Con Google è più facile che mai cercare la sintassi.

Per questo caso particolare, prova

Google: inserisci sito: microsoft.com

Il primo risultato sarà http://msdn.microsoft.com/en-us/library/ms174335.aspx

scorrere fino all'esempio ("Uso delle opzioni SELEZIONA ed ESEGUI per inserire dati da altre tabelle") se trovi difficile interpretare la sintassi fornita nella parte superiore della pagina.

[ WITH <common_table_expression> [ ,...n ] ]
INSERT 
{
        [ TOP ( expression ) [ PERCENT ] ] 
        [ INTO ] 
        { <object> | rowset_function_limited 
          [ WITH ( <Table_Hint_Limited> [ ...n ] ) ]
        }
    {
        [ ( column_list ) ] 
        [ <OUTPUT Clause> ]
        { VALUES ( { DEFAULT | NULL | expression } [ ,...n ] ) [ ,...n     ] 
        | derived_table       <<<<------- Look here ------------------------
        | execute_statement   <<<<------- Look here ------------------------
        | <dml_table_source>  <<<<------- Look here ------------------------
        | DEFAULT VALUES 
        }
    }
}
[;]

Questo dovrebbe essere applicabile per qualsiasi altro RDBMS disponibile lì. Non ha senso ricordare tutte le sintassi per tutti i prodotti IMO.


Per ottenere solo un valore in un valore multi INSERT da un'altra tabella ho fatto quanto segue in SQLite3:

INSERT INTO column_1 ( val_1, val_from_other_table ) 
VALUES('val_1', (SELECT  val_2 FROM table_2 WHERE val_2 = something))

Potresti provare questo se vuoi inserire tutte le colonne usando la tabella SELECT * INTO .

SELECT  *
INTO    Table2
FROM    Table1;

Questo è un altro esempio che utilizza i valori con select:

INSERT INTO table1(desc, id, email) 
SELECT "Hello World", 3, email FROM table2 WHERE ...

Questo ha funzionato per me:

insert into table1 select * from table2

La frase è leggermente diversa da quella di Oracle.


Se si passa al percorso INSERT VALUES per inserire più righe, assicurarsi di delimitare i VALORI nei set usando le parentesi, quindi:

INSERT INTO `receiving_table`
  (id,
  first_name,
  last_name)
VALUES 
  (1002,'Charles','Babbage'),
  (1003,'George', 'Boole'),
  (1001,'Donald','Chamberlin'),
  (1004,'Alan','Turing'),
  (1005,'My','Widenius');

Altrimenti, MySQL obietta che "Il conteggio delle colonne non corrisponde al conteggio dei valori alla riga 1" e finisci per scrivere un post triviale quando finalmente capisci cosa fare al riguardo.


INSERT INTO FIRST_TABLE_NAME (COLUMN_NAME)
SELECT  COLUMN_NAME
FROM    ANOTHER_TABLE_NAME 
WHERE CONDITION;

select *
into tmp
from orders

Sembra carino, ma funziona solo se tmp non esiste (crea e riempie). (SQL sever)

Per inserire nella tabella tmp esistente:

set identity_insert tmp on

insert tmp 
([OrderID]
      ,[CustomerID]
      ,[EmployeeID]
      ,[OrderDate]
      ,[RequiredDate]
      ,[ShippedDate]
      ,[ShipVia]
      ,[Freight]
      ,[ShipName]
      ,[ShipAddress]
      ,[ShipCity]
      ,[ShipRegion]
      ,[ShipPostalCode]
      ,[ShipCountry] )
      select * from orders

set identity_insert tmp off






ansi-sql-92