2009-03-02 9 views
13

En el siguiente diagrama hay una relación 1: 1 entre 'DodgyOldTable' y 'MainTable'. La tabla 'Opción' contiene registros con 'OptionVal1', 'OptionVal2' y 'OptionVal3' en el campo 'OptionDesc'. Necesito hacer una inserción en MainTable_Option con una selección de DodgyOldTable. Algo como esto:Realice INSERT con SELECCIONAR para insertar registros múltiples

INSERT MainTable_Option ([MainTableID],[OptionID]) 
SELECT ID, (CASE WHEN OptionVal1 = 'y' THEN 
    (SELECT OptionID 
    FROM Option 
    WHERE OptionDesc = 'OptionVal1') END 
FROM DodgyOldTable 

De ser posible, quiero evitar el uso de varias instrucciones de selección diferentes para realizar la operación de inserción.

alt text http://www.freeimagehosting.net/uploads/863f10bf5f.jpg

+0

Tal vez sea solo yo, pero no puedo ver la imagen adjunta. – Learning

+0

@Learning: mi proxy corporativo presumido bloquea el sitio de alojamiento de imágenes. Quizás sea algo como esto para ti también. – Tomalak

Respuesta

27
INSERT 
    MainTable_Option 
    (
    MainTableID, 
    OptionID 
) 
SELECT 
    d.ID, 
    o.OptionId 
FROM 
    DodgyOldTable d 
    INNER JOIN Option o ON 
    (d.OptionVal1 = 'Y' AND o.OptionDesc = 'OptionVal1') OR 
    (d.OptionVal2 = 'Y' AND o.OptionDesc = 'OptionVal2') OR 
    (d.OptionVal3 = 'Y' AND o.OptionDesc = 'OptionVal3') 
+0

Brillante! ¡Sabía que tenía que haber una mejor manera! –

+0

Me alegra ayudar. ;-) – Tomalak

0

diría que un script de migración manual sería más fácil de usar y luego tratar de hacerlo de una sola consulta SQL, si eso es una opción.

1

quizás no sea la solución más eficiente, pero al usar una unión, esto debería funcionar.

INSERT MainTable_Option ([MainTableID],[OptionID]) 
SELECT ID, (SELECT OptionID FROM Option WHERE OptionDesc = 'OptionVal1') 
FROM DodgyOldTable dot 
WHERE OptionVal1 = 'y' 
UNION SELECT ID, (SELECT OptionID FROM Option WHERE OptionDesc = 'OptionVal2') 
FROM DodgyOldTable dot 
WHERE OptionVal2 = 'y' 
UNION SELECT ID, (SELECT OptionID FROM Option WHERE OptionDesc = 'OptionVal3') 
FROM DodgyOldTable dot 
WHERE OptionVal3 = 'y' 
+0

@Lieven: Sin ánimo de ofender, pero no creo que sea necesario incluir un saludo y un cierre en sus respuestas. – Tomalak

+0

@Tomalak, sin ofender. No estaba enterado de eso. Considero que es una cortesía estándar en las conversaciones por correo. Por última vez, saludos, Lieven :) –

+0

@Lieven: Nuevamente, no me ofenda, pero me tomé la libertad de quitar el saludo y el cierre para mejorar la legibilidad. –

0

Usted podría UNIÓN selecciona todos juntos para dar un conjunto de resultados, sino que depende de sus razones para no querer que los múltiples selecciona - si hay demasiados o el número de selecciona pueden cambiar con frecuencia todavía estará un dolor para modificar la consulta con los seleccionados adicionales. Desafortunadamente, creo que tendrá que colocar la lógica en algún lugar que determine qué bit (s) de DodgyOldTable asignan a la nueva estructura y escribir un script de migración (o paquete SSIS) para migrar de forma masiva (si se trata de un trabajo aislado) o UNION sus resultados juntos ...

INSERT MainTable_Option ([MainTableID],[OptionID]) 
SELECT ID, (CASE WHEN OptionVal1 = 'y' THEN (SELECT OptionID FROM Option WHERE OptionDesc = 'OptionVal1') END 
FROM DodgyOldTable 
WHERE OptionVal1 = 'y 
UNION 
SELECT ID, (CASE WHEN OptionVal2 = 'y' THEN (SELECT OptionID FROM Option WHERE OptionDesc = 'OptionVal2') END 
FROM DodgyOldTable 
WHERE OptionVal2 = 'y 
... 
1

Mi experiencia es que a menudo es más fácil y más fácil de leer para dividirlo en trozos más pequeños. Por lo tanto, no intente hacer todo en una sola consulta. Especialmente cuando está realizando scripts de migración, esto no debería ser un problema.

Anote los pasos, tal vez introduzca una tabla temporal, escriba los scripts para migrar sus datos y ¡ya está listo!

1

¿Qué hay de la solución CROSS JOIN?

DECLARE @DodgyOldTable TABLE (ID INT, OptionVal1 CHAR, OptionVal2 CHAR, 
    OptionVal3 CHAR) 
INSERT INTO @DodgyOldTable 
SELECT 1, 'y', 'n', 'y' UNION 
SELECT 2, 'y', 'n', 'n' UNION 
SELECT 3, 'n', 'n', 'y' UNION 
SELECT 4, 'y', 'y', 'y' UNION 
SELECT 5, 'n', 'n', 'n' 

DECLARE @Option TABLE (OptionID INT, OptionDesc VARCHAR(100)) 
INSERT INTO @Option 
SELECT 1, 'OptionVal1' UNION 
SELECT 2, 'OptionVal2' UNION 
SELECT 3, 'OptionVal3' 

SELECT ID, OptionID FROM 
(
    SELECT 
     ID, 
     CASE  
      WHEN (OptionVal1 = 'y' AND OptionDesc = 'OptionVal1') 
      OR (OptionVal2 = 'y' AND OptionDesc = 'OptionVal2') 
      OR (OptionVal3 = 'y' AND OptionDesc = 'OptionVal3') 
      THEN OptionID 
      ELSE NULL 
     END AS OptionID 
    FROM @DodgyOldTable DOT CROSS JOIN @Option O 
)CRS 
WHERE OptionID IS NOT NULL 
Cuestiones relacionadas