2017-04-16 1 views
0

Je veux juste INSERT tout enregistrement à la base de données si ont primaire dupliqué, il mettra à jour primaire. Mais je ne sais pas pourquoi il dit toujours l'erreur "Point-virgule manquant (;) à la fin de l'instruction SQL.". Je sais que dans VB.NET il n'y a pas de semicolor pour l'instruction sql, je pense qu'il y a quelque chose qui ne va pas dans mon instruction sql. lorsque je supprime une partie "ON DUPLICATE KEY UPDATE StudentID = @ StudentID" Il insère l'enregistrement OK. S'il vous plaît me signaler si je manqué quelque choseImpossible d'utiliser "INSERT INTO table VALUES() SUR DUPLICATE KEY UPDATE" dans VB.NET

Voici mon code

Private Sub btnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSave.Click 
    cnn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\1_Project\Project_of_VB_Net\AccessDatabase\StudentDatabase.accdb" 
    cmd.Connection = cnn 
    For Each dr In dt.Rows 
     cmd.CommandText = "INSERT INTO StudentData(ID,StudentName,StudentID,StudentClass) VALUES(@ID,@StudentName,@StudentID,@StudentClass) ON DUPLICATE KEY UPDATE [email protected]" 
     cmd.Parameters.AddWithValue("@ID", dr("ID")) 
     cmd.Parameters.AddWithValue("@StudentName", dr("StudentName")) 
     cmd.Parameters.AddWithValue("@StudentID", dr("StudentID")) 
     cmd.Parameters.AddWithValue("@StudentClass", dr("StudentClass")) 
     cnn.Open() 
     cmd.ExecuteNonQuery() 
     cnn.Close() 
    Next 
End Sub 
+1

Vous ne pouvez pas utiliser cette syntaxe avec Access – Steve

+1

MS Access n'est pas MySQL – Plutonix

Répondre

1

Vous ne pouvez pas utiliser cette syntaxe avec Access. Il ne comprend tout simplement pas.
Si vous devez vérifier si l'enregistrement existe alors vous besoin de quelque chose comme ça

Private Sub btnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSave.Click 
    Dim update = "UPDATE StudentData SET StudentName = @StudentName, 
        StudentID = @StudentID, StudentClass = @StudentClass 
        WHERE ID = @ID" 
    Dim insert = "INSERT INTO StudentData 
        (StudentName,StudentID,StudentClass,ID) 
        VALUES(@StudentName,@StudentID,@StudentClass,@ID)" 
    cnn.ConnectionString = "....." 
    cmd.Connection = cnn 
    For Each dr In dt.Rows 
     ' This is important, at each loop you need to add again 
     ' the parameters and not let the previous one still be 
     ' in the first positions 
     cmd.Parameters.Clear() 
     cmd.CommandText = update 
     cmd.Parameters.AddWithValue("@StudentName", dr("StudentName")) 
     cmd.Parameters.AddWithValue("@StudentID", dr("StudentID")) 
     cmd.Parameters.AddWithValue("@StudentClass", dr("StudentClass")) 
     cmd.Parameters.AddWithValue("@ID", dr("ID")) 
     cnn.Open() 
     Dim count = cmd.ExecuteNonQuery() 
     if count = 0 Then 
      cmd.CommandText = insert 
      cmd.ExecuteNonQuery() 
     End If 
     cnn.Close() 
    Next 
End Sub 

En d'autres termes, vous essayez de mettre à jour l'enregistrement avec la touche = ID. Si vous avez réussi, le résultat de ExecuteNonQuery sera le nombre ou les lignes mises à jour (probablement 1). Si vous échouez, vous pouvez utiliser l'insertion.

Notez également que pour éviter une logique complexe, j'ai déplacé la déclaration et l'insertion du paramètre @ID pour être le dernier. Cela permet à votre requête de partager le même ensemble de paramètres à la fois pour la commande UPDATE et pour la commande INSERT.
Dans OleDb, les paramètres ne sont pas reconnus par leur nom, mais par leur position. Le paramètre ID doit donc être le dernier pour l'insertion et la commande de mise à jour de manière à ce que les valeurs soient identiques. paramètres substituables.

+0

Merci pour votre code, j'ai vérifié avec lui, mais j'ai eu un problème, il suffit de courir pour le premier enregistrement. Je veux dire que lorsque j'ajoute 1 enregistrement (appel enregistrement A), compte = 0 -> insérer l'enregistrement A ok, puis je mettre à jour l'enregistrement A, compte = 1 -> mettre à jour l'enregistrement A ok. Maintenant, si j'insère l'enregistrement B, compte toujours égal à 1 -> mise à jour et l'enregistrement B n'est pas inséré dans la base de données – Bruce

+0

Ma faute. La collection de paramètres doit être effacée à chaque boucle. Le problème est dû à nouveau à la nature positionnelle des paramètres dans oledb. La deuxième boucle ajoute un autre ensemble de paramètres mais OleDb continue à utiliser le premier ensemble (avec les mêmes valeurs) car ils apparaissent avant les derniers ajoutés – Steve

+0

Y a-t-il une fonction supportée par vn.net pour effacer chaque boucle? – Bruce