在大型UPDATE操作中参数化所有JOIN数据

时间:2015-07-29 14:48:31

标签: sql sql-server

我有一个应用程序,它使用SQL Server表中的数据对对象进行大量更新,然后写入更新对象'数据在一个查询中返回到数据库。我试图将其转换为参数化查询,以便我不必进行手动转义,转换等。

这是最直接的示例查询:

UPDATE TestTable
SET [Status] = DataToUpdate.[Status], City = DataToUpdate.City
FROM TestTable
JOIN
(
    VALUES --this is the data to parameterize
    (1, 0, 'A City'),
    (2, 0, 'Another City')
) AS DataToUpdate(Id, [Status], City) 
ON DataToUpdate.Id = TestTable.Id

我还使用OPENXML来做这件事,但在向查询添加值时,我还是被迫编写了一堆转义代码。关于如何让这更优雅的任何想法?我对ADO.NET / T-SQL解决方案或与平台无关的解决方案持开放态度。

我有一个想法(但我真的不喜欢它的动态)是动态创建参数然后将它们添加到ADO.NET SqlConnection,例如。

for(int i = 0; i < data.Length; i++)
{
    string paramPrefix = string.Format("@Item{0}", i);
    valuesString.AppendFormat("{0}({1}Status)", Environment.NewLine, paramPrefix);
    var statusParam = new SqlParameter(
        string.Format("{0}Status", paramPrefix),
        System.Data.SqlDbType.Int) 
        { Value = data[i].Status };

    command.Parameters.Add(statusParam);
}

1 个答案:

答案 0 :(得分:1)

我不确定您如何存储您的应用数据(而且我没有足够的回复点来发表评论)所以我会认为记录保存在对象CityAndStatus中它由int Id, string Status, string City List<CityAndStatus>中的data组成,名为Status。这样你就可以一次处理一条记录。我将CREATE PROCEDURE updateCityData ( @Id INT ,@Status INT ,@City VARCHAR(50) ) AS BEGIN TRAN UPDATE TestTable SET [Status] = @Status ,City = @City WHERE Id = @Id COMMIT RETURN GO 设为字符串,以便您可以将其转换为应用程序中的int 有了这些假设:

我会在SQL Server中创建一个存储过程https://msdn.microsoft.com/en-us/library/ms345415.aspx,以便在一次更新表中的一条记录。

   SqlConnection cn = new SqlConnection(connectionString);
   cn.Open();    
   foreach (CityAndStatus item in data)
   {
    SqlCommand cmd = new SqlCommand("updateCityData",cn);
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.Parameters.AddWithValue("@Id", item.Id);
    cmd.Parameters.AddWithValue("@Status", Convert.ToInt32(item.Status));
    cmd.Parameters.AddWithValue("@City", item.User);
    cmd.ExecuteNonQuery();
    cmd.Dispose();
   }
   cn.Close();

然后,我将从一个foreach循环中调用ADO.NET应用程序中的存储过程https://support.microsoft.com/en-us/kb/310070,该循环遍历您需要更新的每个记录。

GRANT EXECUTE
    ON updateCityData 
    TO whateverRoleYouHaveGivenPermissionToExecuteStoredProcedures

之后你应该好。可能阻碍您的一件事是SQL Server使Web应用程序用户授予执行存储过程的权限。因此,在SQL Server中,您可能需要执行类似的操作以允许应用程序触发存储过程。

if (new FileInfo("yourfilename").Length == 0)
{
//Do something here
}
else
{
//Do something else here
}

祝你好运