2009-03-02 10 views
13

Na poniższym diagramie istnieje zależność 1: 1 między "DodgyOldTable" i "MainTable". Tabela "Opcja" zawiera rekordy z "OptionVal1", "OptionVal2" i "OptionVal3" w polu "OptionDesc". Potrzebuję wstawić do MainTable_Option z wybierz z DodgyOldTable. Coś takiego:Wykonaj INSERT z SELECT, aby wstawić wiele rekordów.

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

Jeśli to możliwe, chcę uniknąć użycia kilku różnych instrukcji wyboru, aby wykonać operację wstawiania.

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

+0

Może to tylko ja, ale nie widzę załączonego zdjęcia. – Learning

+0

@Learning: Moje zadowolone korporacyjne proxy blokuje witrynę hostingu obrazów. Być może jest to coś dla ciebie również. – Tomalak

Odpowiedz

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

Genialny! Wiedziałem, że musi być lepszy sposób! –

+0

Cieszę się, że mogę Ci pomóc. ;-) – Tomalak

0

Powiedziałbym, że instrukcja scenariusz migracji będzie łatwiejsza w użyciu, a następnie próbuje to zrobić w jednym zapytaniu SQL, jeśli jest to możliwe.

1

Być może nie jest to najbardziej wydajne rozwiązanie, ale przy użyciu związku powinno to działać.

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: Bez urazy, ale nie sądzę, że jest potrzeba włączenia zwrotu grzecznościowego i zamknięcia odpowiedzi. – Tomalak

+0

@ Tomalak, bez urazy podjęte. Nie wiedziałem o tym. Uważałem, że jest to standardowa poczta w rozmowach mailowych. Po raz ostatni, pozdrawiam, Lieven :) –

+0

@Lieven: Ponownie bez urazy, ale skorzystałem z możliwości zwrotu grzeczności i zamknięcia, aby poprawić czytelność. –

0

Mogłabyś UNION wszystkich wybiera razem dać jeden zestaw wyników, ale to zależy od powodów, dla których nie chce wielokrotne wybiera - jeśli istnieje zbyt wiele lub numer wybiera mogą często zmieniać będzie ona nadal być ból, aby zmienić zapytanie z dodatkowymi wyborami. Niestety myślę, że będziesz musiał umieścić logikę gdzieś, która określa, który bit (y) mapy DodgyOldTable do nowej struktury i albo napisz skrypt migracyjny (lub pakiet SSIS) do masowej migracji (jeśli jest to jednorazowa praca) lub UNION wyniki razem ...

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

Moje doświadczenie jest często łatwiejsze i bardziej czytelne, aby podzielić go na mniejsze kawałki. Więc nie próbuj robić wszystkiego w jednym zapytaniu. Zwłaszcza jeśli tworzysz skrypty migracyjne, nie powinno to stanowić problemu.

Zapisz kroki, może wprowadzaj tabelę tymczasową, napisz skrypty, aby przenieść swoje dane i gotowe!

1

Co z rozwiązaniem 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 
Powiązane problemy