2010-03-03 4 views
0

J'ai rencontré quelque chose d'étrange, et je ne suis pas sûr exactement pourquoi il se comporte de cette façon. Dans un pour chaque boucle j'ajoute des rangées à une table pour une référence croisée. En utilisant le code suivant:SQLCommand ne pas effacer le texte de commande dans une boucle

For Each cp In pCheckPoints 
    If cp <> String.Empty Then 
     Dim insertSQL As New StringBuilder 
     With insertSQL 
      .Append("INSERT INTO [CheckpointMessage] (") 
      .Append(" [MessageID] ") 
      .Append(", [CheckPoint] ") 
      .Append(") VALUES (") 
      .Append(" @MessageID ") 
      .Append(", @Checkpoint ") 
      .Append(") ") 
     End With 
     Using objCommand As New SqlCommand(insertSQL.ToString, MySQLConnection) 
      With objCommand.Parameters 
       .AddWithValue("@MessageID", pMessageID) 
       .AddWithValue("@Checkpoint", cp) 
      End With 
      objCommand.ExecuteNonQuery() 
      objCommand.CommandText = String.Empty 
     End Using 
    End If 
Next 

Sans la ligne objCommand.CommandText = String.Empty CommandText est le InsertSQL mais l'ajout qui ne fait pas de sens pour moi parce que je me attends commandText du ObjCommand être vide, car il est dans un bloc utilisant.

+0

qu'entendez-vous par « est le InsertSQL annexant »? Pouvez-vous expliquer cela en termes d'apparence du contenu, pendant le débogage? – shahkalpesh

Répondre

3

Le texte de votre commande est le même à chaque fois. Ne le reconstruisez pas. Essayez ceci:

Dim insertSql As String = _ 
    "INSERT INTO [CheckpointMessage] " & _ 
     "([MessageID], [CheckPoint]) " & _ 
     "VALUES " & _ 
     "(@MessageID, @ChceckPoint)" 

Using cmd As New SqlCommand(insertSql, MySQLConnection) 
    cmd.Parameters.Add("@MessageID", SqlDbType.Int).Value = pMessageID 
    cmd.Parameters.Add("@CheckPoint", SqlDbType.NVarChar, 255) ''# I had to guess at this type 

    For Each cp As String In pCheckPoints.Where(Function(c) Not String.IsNullOrEmpty(c)) 
     cmd.Parameters("@CheckPoint").Value = cp 
     cmd.ExecuteNonQuery() 
    Next cp 
End Using 

Il est préférable pour beaucoup de raisons:

  • Le compilateur peut optimiser votre concaténations de chaînes loin, où le StringBuilder forcé faire ce travail au moment de l'exécution
  • paramètres Explicitement typés éviter quelques cas de bord qui peuvent vraiment tuer les performances dans le serveur sql, ou même casser votre requête.
  • Cela ne crée votre chaîne de requête d'insertion une fois, pas une fois par poste de contrôle
  • Cela ne crée un sqlCommand objectera
+0

Ahh, bien sûr. Cela a plus de sens quand même. –

0

Autre que la question initiale, les lignes suivantes ne doivent pas être dans la boucle

Dim insertSQL As New StringBuilder 

     With insertSQL 
      .Append("INSERT INTO [CheckpointMessage] (") 
      .Append(" [MessageID] ") 
      .Append(", [CheckPoint] ") 
      .Append(") VALUES (") 
      .Append(" @MessageID ") 
      .Append(", @Checkpoint ") 
      .Append(") ") 
     End With 

     Using objCommand As New SqlCommand(insertSQL.ToString, MySQLConnection) 

Vous pouvez utiliser la chaîne une fois pour créer une commande avec requête paramétrées et utiliser le même objCommand exemple dans la boucle. La seule chose qui appartient à la boucle est les valeurs dynamiques.

Questions connexes