1

私の目標は、データベースからテーブルを取得し、変更して同じ場所に戻すことです。

セルごとの更新を防ぎ、プロセスを高速化するために、oleDbDataAdapter.Fill/.Update ルーチンを使用することにしました。mdb.DataBase から DataTable へのテーブルの読み取りは成功し、変更は正常に行われましたが、データベースの更新に失敗しました。

問題が発生している場所から 2 つの方法を推測できます。

ポイント1を固定しながら

  • 選択クエリに主キーを含めました
  • dbCommandBuilder.GetUpdateCommand() を使用しようとしました
  • 更新文字列を dbCommandBuilder プロパティからコピーして、文字列パラメーターのように使用しようとしましたが失敗しました。

ポイント2を固定しながら

UpdateCommand.Parameters を使用するオプションと、ループ内のターゲット データベースを行ごと、要素ごとに直接入力するオプションを実現しました。しかし、私はそれを避けて、テーブル全体を一度に更新しようとしています。

私が何を見逃しているのか説明してもらえますか?

ここにコード例があります

                    Dim connetionString As String
                    Dim oledbCnn As OleDbConnection
                    Dim oledbAdapter As OleDbDataAdapter
                    Dim sssql, susql As String

connetionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & sMDBFile & ";"
sssql = "SELECT MAPINFO_ID, " & SFieldName & ", AB_P_PIND, AB_P_CITY, " _
  & "AB_P_DISTR, AB_P_SDISTR, AB_P_STR, AB_P_NUM, AB_P_BLD, AB_P_LIT, AB_P_XTRA, " _
  & "AB_P_XEPT, AB_UINF, AB_P_DONE FROM " & DBTableName
susql = "UPDATE " & DBTableName & " SET AB_P_PIND = @AB_P_PIND, AB_P_CITY = @AB_P_CITY, " _
  & "AB_P_DISTR = @AB_P_DISTR, AB_P_SDISTR = @AB_P_SDISTR, AB_P_STR = @AB_P_STR, " _
  & "AB_P_NUM = @AB_P_NUM, AB_P_BLD = @AB_P_BLD, AB_P_LIT = @AB_P_LIT, AB_P_XTRA = @AB_P_XTRA, " _
  & "AB_P_XEPT = @AB_P_XEPT, AB_UINF = @AB_UINF, AB_P_DONE = @AB_P_DONE WHERE MAPINFO_ID = @MAPINFO_ID"
'susql = "UPDATE TabVer1 SET Адрес = ?, AB_P_PIND = ?, AB_P_CITY = ?, AB_P_DISTR = ?, AB_P_SDISTR = ?, " _
'  & "AB_P_STR = ?, AB_P_NUM = ?, AB_P_BLD = ?, AB_P_LIT = ?, AB_P_XTRA = ?, AB_P_XEPT = ?, " _
'  & "AB_UINF = ?, AB_P_DONE = ? WHERE ((MAPINFO_ID = ?) AND ((? = 1 AND Адрес IS NULL) OR " _
'  & "(Адрес = ?)) AND ((? = 1 AND AB_P_PIND IS NULL) OR (AB_P_PIND = ?)) AND " _
'  & "((? = 1 AND AB_P_CITY IS NULL) OR (AB_P_CITY = ?)) AND ((? = 1 AND AB_P_DISTR IS NULL) " _
'  & "OR (AB_P_DISTR = ?)) AND ((? = 1 AND AB_P_SDISTR IS NULL) OR (AB_P_SDISTR = ?)) AND " _
'  & "((? = 1 AND AB_P_STR IS NULL) OR (AB_P_STR = ?)) AND ((? = 1 AND AB_P_NUM IS NULL) " _
'  & "OR (AB_P_NUM = ?)) AND ((? = 1 AND AB_P_BLD IS NULL) OR (AB_P_BLD = ?)) AND " _
'  & "((? = 1 AND AB_P_LIT IS NULL) OR (AB_P_LIT = ?)) AND ((? = 1 AND AB_P_XTRA IS NULL) OR " _
'  & "(AB_P_XTRA = ?)) AND ((? = 1 AND AB_P_XEPT IS NULL) OR (AB_P_XEPT = ?)) AND " _
'  & "((? = 1 AND AB_UINF IS NULL) OR (AB_UINF = ?)) AND ((? = 1 AND AB_P_DONE IS NULL) OR (AB_P_DONE = ?)))"
' second ver of sussql (under comments) is taken from dbCommandBuilder's properties                    


oledbCnn = New OleDbConnection(connetionString)
Try
   oledbCnn.Open()
   oledbAdapter = New OleDbDataAdapter
   dTable.PrimaryKey = New DataColumn() {dTable.Columns("MAPINFO_ID")}
      'Dim DbCommandBuilder As New OleDbCommandBuilder(oledbAdapter)
      ' here's some illustrations of different ways I've tried with update strings
   oledbAdapter.SelectCommand = New OleDbCommand(sssql, oledbCnn)
      'oledbAdapter.UpdateCommand = DbCommandBuilder.GetUpdateCommand()
   oledbAdapter.UpdateCommand = New OleDbCommand(susql, oledbCnn)

   oledbAdapter.Fill(dTable)

   ''' dTable modification

   dTable.AcceptChanges()
      ' DataTable updates 
   oledbAdapter.Update(dTable)
      ' Database does not
   oledbAdapter.Dispose()
   oledbCnn.Close()

Catch ex As Exception
   MsgBox("Can not open connection ! ")
End Try
4

1 に答える 1

0

コードに問題があります: パラメーターを使用して SQL インジェクションを回避しUsing...End Using、接続、アダプター オブジェクトなどを含む使い捨てオブジェクトの形式を使用します。

当面の問題については、更新するまで AcceptChanges を呼び出さないようにしてください。AcceptChanges は、ダーティな行をマークするフラグです。

oledbAdapter.Update(dTable)
dTable.AcceptChanges()
于 2012-09-04T19:27:42.743 に答える