1

假设我有一个包含以下数据的表。

Id   Value
1  | A
2  | B
3  | C

我需要将此表中的值与一组值同步。我想删除所有不在我的集合中的行,添加那些行并保留匹配的行。

鉴于此值集合:

C,D,E

操作后,我希望该表包含:

Id   Value
3  | C
4  | D
5  | E

我知道大多数需要多个查询的明显解决方案。我正在寻找的是更有效的可能解决方案。我可以在这里以某种方式使用 MERGE 语句吗?

编辑- 集合值在 C# 集合 (List<string>) 中,我使用 .NET 中的标准 SqlConnection/SqlCommand 来执行查询。

这是我认为要注意删除值的事情。但这可能会令人不悦,因为我必须做一些字符串连接才能创建它。

DELETE FROM [MyTable] 
WHERE [Value] NOT IN ('C','D','E')

但随后要添加值,似乎我必须为集合中的每个值创建多个 IF NOT EXISTS THEN INSERT 查询语句。

4

2 回答 2

1

我不认为您可以在单个 SQL 语句中执行此操作,但您可以创建一个存储过程来完成这项工作:

create procedure upsertnewrecords(
   @collection varchar(max)
  ) as
begin
  delete 
  from yourtable 
  where charindex(','+value+',', ','+@collection+',') = 0

  ;with cte as (
    select split.t.value('.', 'VARCHAR(100)') newvalue  
    from (
      select cast ('<M>' + replace(@collection, ',', '</M><M>') + '</M>' as xml) as String    
    ) t 
    cross apply String.nodes ('/M') AS Split(t)  
  )

  insert into yourtable
  select newvalue 
  from cte
  where newvalue not in 
    (select value from yourtable)
end

此存储过程首先用于CHARINDEX删除不在当前列表中的值,然后用于CROSS APPLY将逗号分隔列表转换为表值列表,最后通过公用表表达式插入这些值。

于 2013-07-09T01:26:00.063 回答
0

好的,所以您的收藏在 C# 列表中。这使得这更容易。这不是最有效的方法,因为它涉及大量查询,并且使用字典会更好地工作,但如果您没有时间紧迫并且不想使用字符串连接来做一个复杂的查询。

using (SqlConnection connection = new SqlConnection(.....))
{
   connection.Open;

   using (SqlCommand command = new SqlCommand("SELECT ID, Value FROM Table"))
   {
      using (SqlDataReader reader = SqlCommand.ExecuteReader())
      {
         while (reader.Read())
         {
             if (THELIST.Contains(reader["Value"].ToString())
             {

                  THELIST.Remove(reader["Value"].ToString());
             }
             else
             {
                  //Execute a SqlCommand in here to do a DELETE where ID = reader["ID"]
             }

         }

      }

   }

   //Now that you've deleted all the ones that aren't in this list, go through what's left in the list and insert them (only the ones that aren't in the database will be left, since you deleted them as they were found

   foreach (string thing in THELIST)
   {
    //Execute a SqlCommand to do an insert into the database
   }

}
于 2013-07-09T01:16:23.313 回答