2009-03-02 14 views
13

Nello schema seguente c'è una relazione 1: 1 tra "DodgyOldTable" e "MainTable". La tabella 'Opzione' contiene record con 'OptionVal1', 'OptionVal2' e 'OptionVal3' nel campo 'OptionDesc'. Ho bisogno di fare un inserto in MainTable_Option con una selezione da DodgyOldTable. Qualcosa del genere:Esegui INSERISCI con SELEZIONA per inserire più record

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

Se possibile, desidero evitare di utilizzare diverse istruzioni di selezione diverse per eseguire l'operazione di inserimento.

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

+0

Forse sono solo io ma non riesco a vedere l'immagine allegata. – Learning

+0

@Learning: il mio proxy aziendale compiaciuto blocca il sito di hosting delle immagini. Forse è qualcosa di simile anche per te. – Tomalak

risposta

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! Sapevo che doveva esserci un modo migliore! –

+0

Felice di aiutare. ;-) – Tomalak

0

Direi che uno script di migrazione manuale sarebbe più facile da usare poi cercando di farlo in una singola query SQL, se questa è un'opzione.

1

forse non la soluzione più efficiente ma utilizzando un sindacato, questo dovrebbe funzionare.

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: nessuna offesa, ma non credo che sia necessario includere un saluto e una chiusura nelle risposte. – Tomalak

+0

@Tomalak, senza offesa. Non ero conscio di ciò. L'ho considerato una cortesia standard nelle conversazioni via mail. Per l'ultima volta, saluti, Lieven :) –

+0

@Lieven: Ancora nessuna offesa, ma mi sono preso la libertà di rimuovere il saluto e la chiusura per migliorare la leggibilità. –

0

Si potrebbe UNIONE tutti seleziona insieme per dare un set di risultati, ma dipende dalle vostre ragioni per non volere le molteplici seleziona - se ci sono troppi o il numero di seleziona possono cambiare frequentemente sarà ancora un dolore per modificare la query con i selettivi aggiuntivi. Sfortunatamente penso che dovrai mettere la logica da qualche parte che determina quale bit (s) di DodgyOldTable mappare alla nuova struttura e scrivere uno script di migrazione (o pacchetto SSIS) per eseguire la migrazione di massa (se questo è un lavoro singolo) o UNION i risultati insieme ...

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

La mia esperienza è che è spesso più facile e più leggibile per dividere in su in pezzi più piccoli. Quindi non provare a fare tutto in un'unica query. Soprattutto quando si stanno creando script di migrazione questo non dovrebbe essere un problema.

Annotare i passaggi, magari introdurre una tabella temporanea, scrivere gli script per migrare i dati e si è pronti per partire!

1

E la soluzione 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 
Problemi correlati