我有一个应用程序,它使用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);
}
答案 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
}
祝你好运