2011-11-27 9 views
5

ScenarioCome inserire record in SQL con valori cercati?

ho bisogno di aggiornare un database SQL 2008 giornalmente tramite un foglio di calcolo (l'unica opzione disponibile). Il formato è piuttosto semplice, tuttavia ci sono potenzialmente milioni di record. Column1 e Column3 avranno molti valori duplicati predefiniti, già estratti in tabelle separate.

foglio elettronico Esempio di configurazione

Column1 Column2 Column3 
Apple 10  Red 
Apple 20  Red 
Apple 15  Blue 
Apple 21  Green 
Orange 10  Orange 
Orange 7  Orange 
Orange 9  Red 
Orange 70  Blue 
Orange 10  Blue 

DB

mio database è configurato con tre tavoli separati:

//Lookup_Column1 
id type 
1 Apple 
2 Orange 

//Lookup_Column3 
id type 
1 Red 
2 Blue 
3 Green 
4 Orange 

//Main - this is what should be inserted, after Column1 
//and Column2 are matched to their respective ID's 
key Column1 Column2 Column3 
1 1  10  1 
2 1  20  1 
3 1  15  2 
4 1  21  3 
5 2  10  4 
6 2  7  4 
7 2  9  1 
8 2  70  2 
9 2  10  2 

Domanda

Come posso scrivere l'SQL per inserire record che corrispondono alle informazioni delle tabelle di ricerca? Come posso andare da questo:

INSERT INTO Main(Column1, Column2) VALUES ('Apple', 10, 'Red'); 

A tal:

INSERT INTO Main(Column1, Column2) VALUES (1, 10, 1); 
//pulled from lookup tables, where Apple = 1 and Red = 1 
+0

Come pensate di portare i dati del foglio di calcolo in sql-server? –

risposta

5

si potrebbe provare qualcosa di simile:

INSERT INTO Main(Column1, Column2, Column3) VALUES 
    (
    (SELECT id FROM Lookup_Column1 WHERE type = 'Apple'), 
    10, 
    (SELECT id FROM Lookup_Column3 WHERE type = 'Red') 
    ); 

Non c'è nessuna tolleranza d'errore, ma avrebbe funzionato fino a quando si può analizzare i valori del foglio di calcolo in istruzioni SELECT.

+0

Grazie! Questo ha fatto il trucco, breve e dolce. – Paul

2

La fonte di dati che inserita in una tabella è definito come

VALUES ({ DEFAULT | NULL | expression } [ ,...n ]) [ ,...n ] 
      | derived_table 
      | execute_statement 
      | <dml_table_source> 
      | DEFAULT VALUES 

Quindi possiamo utilizzare un derived_table che è definita come

derived_table

È una qualsiasi istruzione SELECT valida che restituisce s righe di dati da caricare nella tabella. L'istruzione SELECT non può contenere un'espressione di tabella comune (CTE) .

INSERT INTO 
    MAIN 
(Column1, Column2, column3) 

SELECT 
    lc1.id, 
    10, 
    lc2.id 
FROM 
    Lookup_Column1 lc1, 
    Lookup_Column2 lc2 
    WHERE 
    lc1.type = 'Apple' 
    and 
    lc2.type = 'Red' 

Per ulteriori informazioni consultare INSERT (Transact-SQL)

Se si potesse ottenere i valori del foglio di calcolo in una tabella di gestione temporanea (o sono legati al foglio di calcolo direttamente utilizzando un server collegato o OPENDATASOURCE) si potrebbe cambiare il vostro clausola INSERT per

INSERT INTO 
    MAIN 
    (Column1, Column2, column3) 
SELECT 
    lc1.id, 
    s.column2, 
    lc2.id 

FROM 
    OPENDATASOURCE('Microsoft.Jet.OLEDB.4.0', 
      'Data Source=C:\YourdataSource.xls;Extended Properties=EXCEL 5.0')...[Sheet1$] s 
    INNER JOIN Lookup_Column1 lc1 
    ON s.column1 = lc1.type 
    INNER JOIN Lookup_Column2 lc2 
    ON s.column3 = lc2.type 

Ciò consentirebbe di rimuovere il ciclo che stai pensando di fare attualmente.

+0

Com'è migliore della risposta di BryceAtNetwork23, che mi sembra più semplice? (anche se entrambe le risposte funzionano) – Paul

+0

Se si stanno elaborando i record uno alla volta, sono uguali. Se si utilizza una tabella di gestione temporanea o OPENDATASOURCE per elaborarli tutti in una volta, è necessario utilizzare un derivato –

+0

Compreso e grazie del proprio aiuto. Sfortunatamente il tuo metodo non è disponibile per me. – Paul

Problemi correlati