我有一个执行存储过程的Web服务。我的 Web 服务函数返回字符串 []。有时我需要多次调用 Web 服务。
出于优化原因,我考虑向我的 Web 服务添加一个函数,该函数在 for 循环中多次执行存储过程。这样,Web 服务只调用一次,而不是多次调用。
1-我的想法正确吗?
2-下面是我的代码,只有特定于上述问题的部分。
3-使用for循环无法做到这一点吗?
我的问题:如果我只使用此代码调用存储过程一次,它可以工作,但是一旦它更多(for 循环第二次迭代),就会访问 catch 块。
如果您能向我解释为什么会发生这种情况和/或提出解决方案/解决方法,我将不胜感激。
try
{
for (int i = 0; i < number; i++)
{
connection.Open();
cmd = new SqlCommand();
//SqlTransaction transaction;
transaction = connection.BeginTransaction();
cmd.Transaction = transaction;
cmd.Connection = connection;
cmd.Parameters.Clear();
cmd.CommandText = "InsertMsg";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@ID", SqlDbType.VarChar).Value = IDs[i];
cmd.Parameters.Add("@name", SqlDbType.VarChar).Value = names[i];
cmd.Parameters.Add("@age", SqlDbType.DateTime).Value = age;
cmd.ExecuteNonQuery();
data[i] = IDs[i];
transaction.Commit();
}
connection.Close();
return data;
}
catch (SqlException ex)
{
transaction.Rollback();
data[0] = "Error";
return data;
}
}
问题似乎与打开和关闭语句有关。关闭在 for 循环之外,将其更改为
try
{
connection.Open();
transaction = connection.BeginTransaction();
for (int i = 0; i < number; i++)
{
cmd = new SqlCommand();
//SqlTransaction transaction;
cmd.Transaction = transaction;
cmd.Connection = connection;
cmd.Parameters.Clear();
cmd.CommandText = "InsertMsg";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@ID", SqlDbType.VarChar).Value = IDs[i];
cmd.Parameters.Add("@name", SqlDbType.VarChar).Value = names[i];
cmd.Parameters.Add("@age", SqlDbType.DateTime).Value = age;
cmd.ExecuteNonQuery();
data[i] = IDs[i];
transaction.Commit();
}
connection.Close();
return data;
}
catch (SqlException ex)
{
transaction.Rollback();
data[0]="Error";
return data;
}
关闭连接应该在 finally 块内,最好改用 using 语句。此外,如果可能的话,在存储过程中进行循环和事务处理,这将更快。
建立你的连接。Open() 在 loop
插话并提到在这种情况下使用 DataAdapter 可能有一个优势:https://msdn.microsoft.com/en-us/library/aadf8fk2(v=vs.110).aspx
FTA - "ADO.NET 中的批处理支持允许 DataAdapter 将 INSERT、UPDATE 和 DELETE 操作从 DataSet 或 DataTable 分组到服务器,而不是一次发送一个操作。减少到服务器的往返次数通常会导致显著的性能提升。"
我只是很快地关闭了它,所以忽略任何语法错误。 基本上,您要确保利用"使用"语句。 当你使用"using"时,它会在达到代码范围后自动调用Dispose(),这样你就不必担心打开或关闭正在使用的连接。
for (int i = 0; i < number; i++)
{
//Initialize this however you need to
using (SqlConnection connection = new SqlConnection())
{
connection.Open();
using (SqlCommand command =
new SqlCommand("InsertMsg", connection, connection.BeginTransaction())
{
CommandType = CommandType.StoredProcedure
})
{
try
{
command.Parameters.Clear();
command.Parameters.Add("@ID", SqlDbType.VarChar).Value = IDs[i];
command.Parameters.Add("@name", SqlDbType.VarChar).Value = names[i];
command.Parameters.Add("@age", SqlDbType.DateTime).Value = age;
command.ExecuteNonQuery();
data[i] = IDs[i];
command.Transaction.Commit();
}
catch (SqlException ex)
{
command.Transaction.Rollback();
data[0] = "Error";
}
}
}
}
return data;
try
{
connection.Open();
cmd = new SqlCommand();
transaction = connection.BeginTransaction();
cmd.Transaction = transaction;
cmd.Connection = connection;
cmd.CommandText = "InsertMsg";
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter ID = cmd.Parameters.Add("@ID", SqlDbType.VarChar);
SqlParameter name = cmd.Parameters.Add("@name", SqlDbType.VarChar);
SqlParameter age = cmd.Parameters.Add("@age", SqlDbType.DateTime);
for (int i = 0; i < number; i++)
{
ID.Value = IDs[i];
name.Value = names[i];
age.Value = age;
cmd.ExecuteNonQuery();
data[i] = IDs[i];
}
transaction.Commit();
}
catch (SqlException ex)
{
transaction.Rollback();
data[0] = "Error";
}
finally
{
connection.Close();
}
return data;