Выполните INSERT с помощью SELECT, чтобы вставить несколько записей - PullRequest
18 голосов
/ 02 марта 2009

На диаграмме ниже есть соотношение 1: 1 между «DodgyOldTable» и «MainTable». Таблица «Option» содержит записи с «OptionVal1», «OptionVal2» и «OptionVal3» в поле «OptionDesc». Мне нужно сделать вставку в MainTable_Option с выбором из DodgyOldTable. Примерно так:

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

Если возможно, я хочу избегать использования нескольких различных операторов выбора для выполнения операции вставки.

альтернативный текст http://www.freeimagehosting.net/uploads/863f10bf5f.jpg

Ответы [ 6 ]

33 голосов
/ 02 марта 2009
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')
1 голос
/ 02 марта 2009

А как насчет решения 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
1 голос
/ 02 марта 2009

По моему опыту, зачастую проще и удобнее разделить его на более мелкие биты. Так что не пытайтесь делать все в одном запросе. Особенно, когда вы создаете сценарии миграции, это не должно быть проблемой.

Запишите шаги, возможно, представьте временную таблицу, напишите сценарии для переноса ваших данных, и вы готовы!

1 голос
/ 02 марта 2009

возможно, не самое эффективное решение, но с помощью объединения это должно сработать.

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 голосов
/ 02 марта 2009

Вы можете ОБЪЕДИНИТЬ все выборки вместе, чтобы получить один набор результатов, но это зависит от ваших причин, по которым вам не нужны множественные выборки - если их слишком много или число выборок может часто меняться, все равно будет сложно изменить запрос с дополнительным выбором. К сожалению, я думаю, что вам придется поместить логику куда-нибудь, которая определяет, какой бит (ы) карты DodgyOldTable для новой структуры, и либо написать сценарий миграции (или пакет служб SSIS) для массовой миграции (если это одноразовое задание), либо UNION. ваши результаты вместе ...

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
...
0 голосов
/ 02 марта 2009

Я бы сказал, что сценарий ручной миграции будет проще использовать, чем пытаться сделать это в одном SQL-запросе, если это вариант.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...