2017-04-16 27 views
0

プライマリが重複している場合は、すべてのレコードをデータベースにINSERTするだけです。しかし、なぜ私はいつも「SQL文の終わりにセミコロン(;)がありません」というエラーが出ているのか分かりません。私はVB.NETには、SQLステートメントのためのセミカラーがないことを知って、私はそこに何か私のSQLステートメントに間違っていると思う。 「重複キー更新のStudentID = @ StudentID」の部分を削除すると、レコードが挿入されます。ここでは、Accessでその構文を使用することはできません私のコードVB.NETで "INSERT INTOテーブルVALUES()重複キー更新"を使用することはできません

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

Accessでこの構文を使用することはできません – Steve

+1

MS AccessはMySQLではありません – Plutonix

答えて

1

である私が何か

を逃したかどうか私にポイントしてください。それは単にそれを理解していません。あなたはレコードが存在するかどうかを確認する必要がある場合
が、あなたは言い換えれば、この

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 

ようなものが必要には、キー= IDを持つレコードを更新してみてください。成功した場合、ExecuteNonQueryの結果は更新された数(おそらく1)になります。あなたが失敗した場合は、挿入することができます。

複雑なロジックを避けるために、パラメータ@IDの宣言と挿入を最後のものに移動しました。これにより、UPDATEコマンドとINSERTコマンドの両方で、同じセットのパラメーターを照会で使用することができます。
OleDbのパラメータは名前ではなく位置によって認識されます。したがって、IDパラメータは、挿入コマンドと更新コマンドの最後のパラメータである必要があります。パラメータプレースホルダ。

+0

ありがとう、私はそれをチェックしましたが、問題がありました。私は1レコード(コールレコードA)を追加すると、カウント= 0 - >レコードAを挿入してOK、次にレコードAを更新します。カウント= 1 - >レコードAを更新します。レコードBを挿入すると、常に1 - >更新となり、レコードBがデータベースに挿入されません。 – Bruce

+0

私の誤りです。各ループでパラメータコレクションをクリアする必要があります。この問題は、oledbのパラメータの位置的性質によって再び引き起こされます。 2番目のループは別のパラメータセットを追加しますが、最後に追加されたものの前に表示されるため、OleDbは最初のセット(同じ値)を使用し続けます – Steve

+0

vn.netからサポートされている関数はありますか? – Bruce

関連する問題