2012-11-28 32 views
1

我想用不同的ID更新单个命令中的许多行。这些ID应该在查询中传递,如SQL Server:使用不同ID同时更新许多行的最佳实践

Update table 
Set Updated = 1 
where ID is in 
(
    1 
    2 
    3 
) 

更进一步的困难是有两个主键列需要检查。我不想在自己的命令中更新每行,因为服务器往返速度很慢。

什么是更新这样的表的最佳方式是什么?

+0

你是什么由两个主键列是什么意思?一个表只能有一个主键(尽管它可以是一个组合)。 – Oded

+0

你的意思是说你的主键是复合 - 是由多个字段组成的?如果是这样,比**唯一的选择**是单独更新每条记录,那么您可以按照ErikE建议的方式来减少往返行程。 –

+0

什么版本的sql server? – ErikE

回答

3

将表加入包含VALUES子句(SQL 2008)或一系列UNION ALL SELECT的派生表中。

UPDATE T 
SET Col = 1 
FROM dbo.Table T 
INNER JOIN (
    VALUES 
     (1, 3), 
     (3, 5), 
     (5, 7) 
) X (ID1, ID2) 
    ON T.ID1 = X.ID1 
    AND T.ID2 = X.ID2 

对于SQL 2005和更早的版本:

UPDATE T 
SET Col = 1 
FROM dbo.Table T 
INNER JOIN (
    SELECT 1, 3 
    UNION ALL SELECT 3, 5 
    UNION ALL SELECT 5, 7 
) X (ID1, ID2) 
    ON T.ID1 = X.ID1 
    AND T.ID2 = X.ID2 

或者,插入到一个临时表,并加入了这一点。您还可以创建一个存储过程,该存储过程接受包含您需要加入的所有密钥的参数。该参数可以是文本(您将分割),xml或表值参数。

如果数据量非常大,那么您可以考虑将文本文件中的密钥批量加载到表中。

+0

或使用表变量,临时表或表值参数。 – Oded

+0

我已经接近,但在我的手机上打字太慢了! – ErikE

+0

太棒了!非常感谢。这正是我所期待的! –

1

你的语法几乎是正确的。下面就按预期执行:

Update table 
Set Updated = 1 
where ID IN 
(
    1, 
    2, 
    3 
) 

如果您需要匹配的多列,你需要有数据的源包含这些列 - 一个临时表,表变量或表值参数可以工作。你可以加入你的表格并在其上运行更新。

UPDATE table 
SET Updated = 1 
FROM table 
    INNER JOIN otherTable 
    ON table.Col1 = otherTable.Col1 
    AND table.Col2 = otherTable.Col2 
1

您可以根据逗号分隔列表中的单个主键进行更新。 所以你的情况:

update tblTable set updated = 1 where id in (1,2,3) 

您可以使用更新where条件,就像你用SELECT命令。 你没有使用SQL Server的版本规定,但这里是SQL2K联机丛书链接:

http://msdn.microsoft.com/en-us/library/aa260662(v=sql.80).aspx

联机丛书SQL是开始针对这种性质的问题(即命令结构)

的好地方
+1

和复合关键问题? – ErikE

1

这取决于。

如果您的“更新记录的选择”是用编程语言定义的(例如,您正在用c#编写查询,然后将它传递给sql server),最简单的解决方案是生成一系列where子句,如下所示:

OR (KeyColumn1 = @FilterValue1_1 AND KeyColumn2 = @FilterValue2_1) 
OR (KeyColumn1 = @FilterValue1_2 AND KeyColumn2 = @FilterValue2_2) 

如果您选择从另一个查询来直接将其嵌入在更新语句,像这样:

UPDATE 
    [TableToUpdate] 
SET 
    [ColumnToUpdate] = @NewValue 
FROM 
    [TableToUpdate] 
    INNER JOIN [FilterTable] 
     ON [FilterTable].[KeyColumn1] = [TableToUpdate].[KeyColumn1] 
     AND [FilterTable].[KeyColumn2] = [TableToUpdate].[KeyColumn2] 
WHERE 
    [FilterTable].[ColumnToFilter] = @ValueToFilter 

或者这样:

UPDATE 
    [TableToUpdate] 
SET 
    [ColumnToUpdate] = @NewValue 
FROM 
    [TableToUpdate] 
    INNER JOIN 
    (
     SELECT 
      [FilterTable].[KeyColumn1], 
      [FilterTable].[KeyColumn2] 
     FROM 
      [FilterTable] 
     WHERE 
      [FilterTable].[ColumnToFilter] = @ValueToFilter 
    ) 
     AS [Filter] 
     ON [Filter].[KeyColumn1] = [TableToUpdate].[KeyColumn1] 
     AND [Filter].[KeyColumn2] = [TableToUpdate].[KeyColumn2] 

也不像这个:)

;WITH [Filter] AS 
(
    SELECT 
     [FilterTable].[KeyColumn1], 
     [FilterTable].[KeyColumn2] 
    FROM 
     [FilterTable] 
    WHERE 
     [FilterTable].[ColumnToFilter] = @ValueToFilter 
) 
UPDATE 
    [TableToUpdate] 
SET 
    [ColumnToUpdate] = @NewValue 
FROM 
    [TableToUpdate] 
    INNER JOIN [Filter] 
     ON [Filter].[KeyColumn1] = [TableToUpdate].[KeyColumn1] 
     AND [Filter].[KeyColumn2] = [TableToUpdate].[KeyColumn2]