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

时间:2015-04-14 20:30:43

标签: c# stored-procedures try-catch sqlexception

我有一个执行存储过程的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;
    }
}

5 个答案:

答案 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;