使用SELECT执行INSERT以插入多个记录

时间:2009-03-02 10:41:49

标签: sql sql-server sql-server-2005

在下图中,'DodgyOldTable'和'MainTable'之间存在1:1的关系。表'选项'包含'OptionDesc'字段中带有'OptionVal1','OptionVal2'和'OptionVal3'的记录。 我需要使用DodgyOldTable中的select来插入MainTable_Option。像这样:

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

如果可能,我想避免使用几个不同的select语句来执行插入操作。

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

7 个答案:

答案 0 :(得分:32)

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 :(得分:2)

11年后,但可能会帮助某人:

INSERT INTO schema.tableName (col1, col2,col3, col4, col5, col6, col7)
      SELECT col1, 
             col2,
             'Static value',
             CURRENT_TIMESTAMP,
             'Anothe static value', 
             1, 
             (SELECT col7 FROM schema2.anotherTableName)
       FROM schema.tableX;

col1和col2来自同一选择

col3,col5是静态字符串

col4是当前系统时间

col6为Num值,

选择中的

col7返回一个值。

注意:确保带有多个值的选择位于开头。 这是MySQL

答案 2 :(得分:1)

也许不是最有效的解决方案,但通过使用联合,这应该可行。

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'

答案 3 :(得分:1)

我的经验是,将它分成更小的位通常更容易,更易读。因此,不要尝试在一个查询中执行所有操作。特别是在制作迁移脚本时,这应该不是问题。

记下步骤,可能会引入一个临时表,编写脚本来迁移数据,你就可以了!

答案 4 :(得分:1)

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

答案 5 :(得分:0)

我会说手动迁移脚本会更容易使用,然后尝试在单个SQL查询中执行它,如果这是一个选项。

答案 6 :(得分:0)

你可以联合所有的选择来给出一个结果集但是它取决于你不想要多次选择的原因 - 如果有太多或者选择的数量可能经常改变它仍然是一个痛苦的修改带有附加选择的查询。不幸的是,我认为你必须将逻辑放在某个地方,确定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
...