【问题标题】:Multiple table updates - avoiding multiple WHERE clauses多个表更新 - 避免多个 WHERE 子句
【发布时间】:2014-01-29 21:54:03
【问题描述】:

我环顾四周寻找一个类似的问题(我确定某处有一个)但找不到。

我有一个 ID 列表,对于每个 ID,我需要将该 ID 行的另一列更新为相同的字符串。

基本上,我想要这样的东西:

List<int> uniqueIDs;

UPDATE my_table
SET certainColumn = "foo bar"
WHERE uniqueID = uniqueIDs[0]
    OR uniqueID = uniqueIDs[1]
    ...
    OR uniqueID = uniqueID[uniqueIDs.Length-1]

我知道这可以通过将其包围在 for/foreach 循环中来实现,但我想知道是否有更好的方法来完成这项工作,可能在一个数据库连接中?

非常感谢任何帮助。

【问题讨论】:

  • 您的示例有一行 C#,后跟一条 SQL 语句 - 您是尝试在 C# 中还是在 SQL 中实现这一点?或者您想弄清楚如何一次性将列表传递给 SQL?
  • 好问题。我主要只是将两者结合起来以更好地展示我的最终目标。我想在 C# 中制定一些 sql 更新然后执行它。所以我猜是后者!
  • 您会为多个唯一ID 更新certainColumn 吗?你有一个他们唯一ID的列表??如果我错了,请纠正我??
  • 我的建议是混合方法。查看 SQL 2008 或更高版本中的表值参数。您可以从 c# 传递一个表(SQL 中自定义的表类型),然后在 WHERE 子句中使用一个简单的 IN 子句,封装在一个存储过程中。
  • @M.Ali 你是对的。多行需要将某些列更新为“foo bar”。

标签: c# sql sql-server


【解决方案1】:

嗯,您可以使用 TVP。首先,在您的服务器上创建它:

CREATE TYPE dbo.UniqueIDs AS TABLE(ID INT PRIMARY KEY);

然后是一个存储过程:

CREATE PROCEDURE dbo.UpdateByID
  @tvp dbo.UniqueIDs READONLY
AS
BEGIN
  SET NOCOUNT ON;

  UPDATE t SET certainColumn = 'foo bar'
    FROM dbo.my_table AS t
    INNER JOIN @tvp AS tvp
    ON t.uniqueID = tvp.ID;
END

或者:

CREATE PROCEDURE dbo.UpdateByID
  @tvp dbo.UniqueIDs READONLY
AS
BEGIN
  SET NOCOUNT ON;

  UPDATE t SET certainColumn = 'foo bar'
    FROM dbo.my_table AS t
    WHERE EXISTS (SELECT 1 FROM @tvp
      WHERE ID = t.uniqueID);
END

然后使用DataTable 代替List 在C# 应用程序中保存您的ID,并调用存储过程,将@tvp 作为Structured 参数传递。我在这个网站上发布了 C# 方面的简单示例:

【讨论】:

    【解决方案2】:
    var query = "UPDATE my_table
    SET certainColumn = 'foo bar'
    WHERE uniqueID in (" + String.Join(",", uniqueIDs) + ")"
    

    【讨论】:

    • 有谁知道查询字符串的长度是否有字符限制?最多有可能(但不太可能)进行大约 5000 次更新,这意味着查询中计算逗号的有 (5000 * 2) 个额外字符。希望不会,因为我喜欢这个解决方案。
    • 仅仅因为您可以创建一个 100 KB 的 SQL 字符串并有一个包含 5000 个项目的 IN 列表并不意味着您应该恕我直言。
    • @njenson 我能想到很多限制。我的建议是使用良好的做法创建一个临时变量,然后使用 where 子句,就像一个合适的程序员应该做的那样
    • 我同意以上两个cmets。虽然这一切都取决于你的情况。如果它不是一个真正重要的应用程序,我会这样留下它,我的感觉是它不是,因为谁还会为任何严肃的应用程序连接字符串???
    【解决方案3】:

    我猜你可以做这样的事情。在一些 TempTable 或表变量中获取您的 ID 列表,并在更新语句中使用 IN 运算符。像这样的......

    UPDATE my_table
    SET certainColumn = 'foo bar'
    WHERE uniqueID IN (SELECT uniqueID 
                       FROM @List_Table)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-11
      • 1970-01-01
      • 2020-12-03
      • 2021-11-06
      • 2013-02-26
      • 2020-09-28
      相关资源
      最近更新 更多