1

我想用不同的 ID 在一个命令中更新许多行。这些 ID 应该像这样在查询中传递

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

另一个困难是要检查两个主键列。我不想在自己的命令中更新每一行,因为它非常慢,因为服务器往返。

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

4

4 回答 4

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 或表值参数。

如果数据量非常巨大,那么您可能会考虑将文本文件中的键批量加载到表中。

于 2012-11-28T09:48:17.427 回答
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
于 2012-11-28T09:47:07.103 回答
1

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

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

您可以像使用 SELECT 命令一样使用 update where 条件。您没有规定 SQL Server 的版本,但这里是 SQL2k 联机丛书链接:

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

SQL 联机丛书是解决此类问题(即命令结构)的好地方

于 2012-11-28T09:50:01.947 回答
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]
于 2012-11-28T10:08:56.193 回答