2011-11-27 22 views
5

Escenario¿Cómo insertar registros en SQL con valores buscados?

necesito actualizar una base de datos SQL 2008 diariamente a través de una hoja de cálculo (la única opción disponible). El formato es bastante básico, sin embargo, hay potencialmente millones de registros. Column1 y Column3 tendrán muchos valores duplicados predefinidos, ya extraídos en tablas separadas.

hoja de cálculo de muestra de configuración

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

Mi base de datos está configurado con tres mesas separadas:

//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 

Pregunta

¿Cómo puedo escribir el SQL para insertar registros que coincidan con la información de las tablas de búsqueda? ¿Cómo puedo pasar de esto:

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

A esto:

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

¿Cómo piensas llevar los datos de la hoja de cálculo al servidor sql? –

Respuesta

5

usted podría intentar algo como esto:

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

No hay ninguna tolerancia a fallos, pero que iba a funcionar todo el tiempo que podría analizar los valores de la hoja de cálculo en las instrucciones SELECT.

+0

¡Gracias! Esto hizo el truco, corto y dulce. – Paul

2

La fuente de datos que se inserta en una tabla se define como

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

lo tanto, podemos utilizar un derived_table que se define como

derived_table

Es cualquier instrucción SELECT válida que devuelve s filas de datos para cargar en la tabla. La instrucción SELECT no puede contener una expresión de tabla común (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' 

Para obtener más información, véase INSERT (Transact-SQL)

Si usted podría conseguir sus valores de hoja de cálculo en una tabla de ensayo (o vinculados a la hoja de cálculo directamente a través de un servidor vinculado o OPENDATASOURCE) que podría cambiar su cláusula INSERT para

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 

Esto le permitiría eliminar el bucle que está pensando en hacer.

+0

¿Cómo es esto mejor que la respuesta de BryceAtNetwork23, que me parece más simple? (aunque ambas respuestas funcionan) – Paul

+0

Si va a procesar los registros de uno en uno, son los mismos. Si usa una tabla de etapas o OPENDATASOURCE para procesarlos todos a la vez, entonces debe usar una tabla derivada –

+0

Entendida, y gracias por su ayuda. Lamentablemente, tu método no está disponible para mí. – Paul

Cuestiones relacionadas