我有一个执行存储过程的Web服务。我的Web服务函数返回string []。 有时我需要多次调用Web服务。
出于优化原因,我考虑在我的Web服务中添加一个函数,该函数在 for循环中多次执行存储过程。这样,Web服务只被调用一次而不是几次。
1 - 我的想法是否正确?
2 - 下面是我的代码,只是特定于上述问题的部分。
3 - 使用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;
}
}
答案 0 :(得分:1)
这些问题似乎与开放和结束的陈述有关。关闭在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语句。如果可能的话,在存储过程中进行循环和事务将更快。
答案 1 :(得分:1)
将你的连接.Open()放在循环
之后答案 2 :(得分:1)
我想提一下,并提到在这种情况下使用DataAdapter可能有一个优势: https://msdn.microsoft.com/en-us/library/aadf8fk2(v=vs.110).aspx
FTA - “ADO.NET中的批处理支持允许DataAdapter将DataSet或DataTable中的INSERT,UPDATE和DELETE操作分组到服务器,而不是一次发送一个操作。往返服务器往往会带来显着的性能提升。“
答案 3 :(得分:1)
我刚刚快速飞过这个,所以忽略任何语法错误。基本上你想确保你正在利用“使用”语句。当您使用“使用”时,它会在达到代码范围后自动调用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;
答案 4 :(得分:0)
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;