2009-03-02 11 views
13

In dem Diagramm unten gibt es eine 1: 1-Beziehung zwischen 'DodgyOldTable' und 'MainTable'. Tabelle 'Option' enthält Datensätze mit 'OptionVal1', 'OptionVal2' und 'OptionVal3' im Feld 'OptionDesc'. Ich muss eine Insert in MainTable_Option mit einer Auswahl aus DodgyOldTable tun. Etwas wie dieses:Führen Sie INSERT mit SELECT aus, um mehrere Datensätze einzufügen

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

Wenn möglich, möchte ich vermeiden, mehrere verschiedene Select-Anweisungen zu verwenden, um die Einfügeoperation durchzuführen.

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

+0

Vielleicht ist es nur ich, aber ich kann das beigefügte Bild nicht sehen. – Learning

+0

@Learning: Mein selbstgefälliger Unternehmens-Proxy blockiert die Image-Hosting-Site. Vielleicht ist es auch so für dich. – Tomalak

Antwort

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

Brilliant! Ich wusste, dass es einen besseren Weg geben musste! –

+0

Gut zu helfen. ;-) – Tomalak

0

Ich würde sagen, dass eine manuelle Migration Skript einfacher wäre, dann zu verwenden, versuchen, es in einer einzigen SQL-Abfrage zu tun, wenn das eine Option.

1

vielleicht nicht die effizienteste Lösung, aber mit einer Union sollte dies funktionieren.

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: Nichts für ungut, aber ich denke nicht, dass es eine Notwendigkeit ist, eine Anrede und ein Schließen in Ihre Antworten aufzunehmen. – Tomalak

+0

@Tomalak, nichts für ungut. Das war mir nicht bewusst. Ich hielt es in Mail-Konversationen für Standard-Höflichkeit. Zum letzten Mal, Grüße, Lieven :) –

+0

@Lieven: Wieder nichts für ungut, aber ich habe mir die Freiheit genommen, die Anrede zu entfernen und zu schließen, um die Lesbarkeit zu verbessern. –

0

Sie könnten UNION zusammen alle wählt eine Ergebnismenge zu geben, aber es hängt davon ab, Ihre Gründe für die nicht die mehrere wählt wollen - wenn es zu viele oder die Anzahl der wählt sind, kann es immer noch häufig ändern sein wird ein Problem, die Abfrage mit den zusätzlichen Auswahlmöglichkeiten zu ändern. Unglücklicherweise denke ich, dass Sie die Logik irgendwo platzieren müssen, die bestimmt, welche Bits von DodgyOldTable der neuen Struktur zugeordnet sind, und entweder ein Migrationsskript (oder SSIS-Paket) für die Massenmigration (wenn es sich um einen einmaligen Auftrag handelt) oder UNION schreiben Ihre Ergebnisse zusammen ...

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

Meine Erfahrung ist es oft einfacher und besser lesbar ist es in kleinere Bits aufzuteilen. Versuchen Sie also nicht, alles in einer einzigen Abfrage zu machen. Besonders wenn Sie Migrationsskripte erstellen, sollte dies kein Problem darstellen.

Schreiben Sie die Schritte auf, führen Sie vielleicht eine temporäre Tabelle ein, schreiben Sie die Skripte, um Ihre Daten zu migrieren, und Sie können loslegen!

1

Was ist mit CROSS JOIN-Lösung?

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 
Verwandte Themen