我在SQL Server Management Studio中运行了一个脚本来测试查询执行的能力。这是批量删除。
DECLARE @Deleted_Rows INT;
SET @Deleted_Rows = 1;
WHILE (@Deleted_Rows > 0)
BEGIN
BEGIN TRANSACTION
DELETE TOP (10000) [dbo].[TableA1]
WHERE [dbo].[TableA1].[Timestamp] < CAST(CONVERT(VARCHAR(20), GETDATE()-40, 112) + ' 00:00:00' AS DATETIME)
SET @Deleted_Rows = @@ROWCOUNT;
COMMIT TRANSACTION
CHECKPOINT
END
结果非常好,所以我打算将它应用于C#代码,因为我的主程序在控制台应用程序中运行。该程序处理SELECT
,UPDATE
,DELETE
。
问题是当用于DELETE
时,会发生异常:
EXECUTE之后的事务计数表示BEGIN和COMMIT语句的数量不匹配
我使用脚本DELETE
的方法:
static async Task StartDeleteRecords(string machname)
{
try
{
int rowsAffected = 0;
string query = "";
using (SqlConnection connection = new SqlConnection(localconnstring))
{
try
{
connection.Open();
query = @"DECLARE @Deleted_Rows INT;
SET @Deleted_Rows = 1;
WHILE (@Deleted_Rows > 0)
BEGIN
BEGIN TRANSACTION
DELETE TOP (10000) [dbo].[@tablename]
WHERE [dbo].[@tablename].[Timestamp] < CAST(CONVERT(VARCHAR(20), GETDATE()-@intervaltime, 112) + ' 00:00:00' AS DATETIME)
SET @Deleted_Rows = @@ROWCOUNT;
COMMIT TRANSACTION
CHECKPOINT
END";
using (SqlCommand command = new SqlCommand(query, connection))
{
command.CommandType = CommandType.Text;
command.Parameters.AddWithValue("@tablename", tablename);
command.Parameters.AddWithValue("@intervaltime", intervaltime);
command.CommandTimeout = 0;
rowsAffected = command.ExecuteNonQuery();
}
connection.Close();
LogEvents("Table name: " + tablename + ", Acquire records: " + lstHouseKeep.Count + ", Affected records: " + rowsAffected, EventLogEntryType.Information);
}
catch (Exception ex)
{
LogEvents("Exception when load data from adapter to generic list. Ex - " + ex.Message, EventLogEntryType.Error);
}
}
}
catch (Exception ex)
{
LogEvents("Exception while start housekeeping records - " + ex.Message, EventLogEntryType.Error);
}
await Task.Delay(100);
}