2015-04-14 3 views
-2

J'ai un service Web qui exécute une procédure stockée. Ma fonction de service Web renvoie la chaîne []. Parfois, j'ai besoin d'appeler le service Web plusieurs fois. Pour des raisons d'optimisation, j'ai pensé à ajouter une fonction à mon service Web qui exécute la procédure stockée plusieurs fois, dans un pour la boucle. De cette façon, le service Web n'est appelé qu'une seule fois au lieu de plusieurs fois.Puis-je exécuter une procédure stockée plusieurs fois dans une boucle for?

1-Est-ce que ma pensée est correcte?

2-Ci-dessous est mon code, uniquement la partie spécifique au problème décrit ci-dessus.

3-Est-ce que ce n'est simplement pas possible de le faire en utilisant une boucle for?

Mon problème: Si je n'utilise ce code que pour appeler la procédure stockée une fois, cela fonctionne, mais dès qu'il y en a plus (pour la boucle se répète une deuxième fois), le bloc catch est accédé.

Si vous pouvez m'expliquer pourquoi cela se produit et/ou suggérer une solution/solution de contournement, j'apprécierais vraiment.

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

Quelle est l'exception que vous obtenez? – maccettura

+1

Avez-vous débogué à travers le code pour voir quoi et pourquoi échoue? – xxbbcc

+0

J'appelle le service Web via une référence Web, donc je ne pouvais pas voir comment le déboguer – SystemFailure

Répondre

1

Les problèmes semblent être liés aux instructions open et close. Fermer est en dehors de la boucle, le modifier comme

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

Fermeture de la connexion doit être à l'intérieur d'un bloc finally, mieux utiliser une instruction en utilisant à la place. Si possible, faites la boucle et la transaction dans la procédure stockée qui sera plus rapide.

+0

Merci pour l'astuce de la transaction dans la procédure stockée. – SystemFailure

1

Mettez votre connection.Open() en dehors la boucle

1

Je voulais sonner et mentionner il y a probablement un avantage à utiliser un DataAdapter dans cette circonstance: https://msdn.microsoft.com/en-us/library/aadf8fk2(v=vs.110).aspx

FTA - « Lot La prise en charge dans ADO.NET permet à un DataAdapter de regrouper les opérations INSERT, UPDATE et DELETE d'un DataSet ou d'un DataTable sur le serveur, au lieu d'envoyer une opération à la fois. gains de performance. "

1

Je viens juste de l'éteindre, donc ignorez les erreurs de syntaxe. Fondamentalement, vous voulez vous assurer que vous profitez des instructions "using". Lorsque vous utilisez un "using", il appelle automatiquement Dispose() après que la portée du code a été atteinte, de cette façon vous n'avez pas à vous soucier de l'ouverture ou la fermeture d'une connexion qui est en cours d'utilisation.

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; 
+0

Ne fonctionne toujours pas. Et je ne peux pas déboguer, car le service Web est hébergé sur IIS mais pas sur la même machine où mon projet winforms est en cours d'exécution – SystemFailure

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;