我可以在for循环中多次执行一个存储过程吗?

Can I execute a stored procedure many time in a for loop?

我有一个执行存储过程的网络服务。我的网络服务函数 returns string[]。 有时需要多次调用Web服务

出于优化原因,我考虑向我的 Web 服务添加一个函数,该函数在 for 循环 中多次执行存储过程。这样,Web 服务只被调用一次而不是多次。

1-我的想法是否正确?

2-下面是我的代码,只有针对上述问题的部分。

3-难道不能使用 for 循环来做到这一点吗?

我的问题:如果我只使用这段代码调用存储过程一次,它可以工作,但是一旦更多(for循环迭代第二次),访问了 catch 块。

如果你能向我解释为什么会这样and/or建议solution/workaround我将不胜感激。

    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;
    }
}

问题似乎与 open 和 close 语句有关。 close在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 语句。另外,如果可能的话,在存储过程中进行循环和事务处理会更快。

将你的 connection.Open() 放在循环之外

我想插话并提到在这种情况下使用 DataAdapter 可能有一个优势: https://msdn.microsoft.com/en-us/library/aadf8fk2(v=vs.110).aspx

自由贸易协定 - "Batch support in ADO.NET allows a DataAdapter to group INSERT, UPDATE, and DELETE operations from a DataSet or DataTable to the server, instead of sending one operation at a time. The reduction in the number of round trips to the server typically results in significant performance gains. "

我只是很快就解决了这个问题,所以请忽略任何语法错误。基本上你想确保你正在利用 "using" 语句。当您使用 "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;