DOBON.NETプログラミング道掲示板

No35585 の記事


■35585 / )  Re[1]: DataAdapter.Updateで構文エラー
□投稿者/ 魔界の仮面弁士 大御所(1570回)-(2024/03/12(Tue) 10:31:36)
  • アイコンNo35582に返信(けいさんの記事)
    > ソフトで、テーブルA全体のデータセットをSELECT文で取得し、
    > 1行ずつ、[フィールドP]を「値」で更新する処理を書いています。
    それはあまり一般的なやり方では無いですね…。今回やろうとしているように、
    DataAdapter か TableAdapter を使う方が手っ取り早いでしょうね。

    仮にループ内で処理するにしても、今のように毎回 OleDbCommand を発行して、
    ad-hoc な SQL をその都度作るようなコードは避けるべきです。ループ処理なら
    OleDbCommand のインスタンス化はループの外で一度だけ行うようにし、
    ループ内では更新値を OldDbParameter で受け渡して、ExecuteNonQuery を
    呼び出すだけのコードにします。


    > System.Data.OleDb Ver8.0.0は、
    > NuGetでインストール済です。
    ということは .NET Framework のプロジェクトではなく、.NET 8 なのですね?


    > こちらですと、※の部分で構文エラーが出ます。
    それは、Visual Basic の構文エラー(コンパイルエラー)では無く、
    JET Database Engine の構文エラー(実行時エラー)なのですよね?

    であれば、実際のエラー内容を公開すべきだと思いますよ。

    何が原因になっているのかは、実際の構文を見てみないと分かりませんが、
    Access 絡みの更新失敗時に良く事故として、たとえばこういったものがあります。

    ・PRIMARY KEY や UNIQUE KEY が無く、更新行を特定可能な SQL コマンドを生成できなかった
     ⇒ 主キーを追加する

    ・フィールド名に予約語が使われており、構文解析に失敗した … NO, DATE など
    ・半角カナや長音記号「ー」など、実行環境によって正しく処理されないフィールド名がある
     ⇒ QuotePrefix / QuoteSuffix を補完する

    ・時刻を持つ日付型フィールドがあるが、UpdateCommand プロパティの該当 Parameter が、
     DbType.DateTime ではなく DbType.Date にマッピングされていて、更新元行の検出に失敗していた
     ⇒ パラメーターの DbType を修正する


    まずは、自動生成される更新クエリの内容を確認するため、
     cb = New OleDbCommandBuilder(da)
    の実行直後に、このようなコードを書いて、正しい更新コマンドが得られているかを確認しましょう。

     da.UpdateCommand = cb.GetUpdateCommand()
     Debug.Print($"{da.UpdateCommand.CommandText}")
     For Each p As OleDbParameter In da.UpdateCommand.Parameters
       Debug.Print($" [{p.ParameterName}], Col=[{p.SourceColumn}], Ver={p.SourceVersion}, DB型={p.OleDbType}, VB型={p.DbType}, Size={p.Size}")
     Next

    なお、元の SQL に近づけるのであれば、
     cb.ConflictOption = ConflictOption.OverwriteChanges
     cb.QuotePrefix = "["
     cb.QuoteSuffix = "]"
    を加えておいた方が良いかもしれませんが、この辺りは任意で。



    > Dim i As Integer
    ループカウンタのような局所的な変数を、コードの先頭で事前宣言すべきではありません。

    VB.NET 2002 といった古いバージョンならいざ知らず、2003 以降では
     For i As Integer = 0 To dr.Length - 1
    のようにして、For 内でしか使われない、ブロック スコープの変数にすべきです。
    (VB2008 以降では、For i As Integer = 0 ではなく For i = 0 と書くのが一般的)

    https://thom.hateblo.jp/entry/2016/12/12/223708
    https://learn.microsoft.com/ja-jp/dotnet/visual-basic/programming-guide/language-features/declared-elements/scope?WT.mc_id=DT-MVP-8907
違反を報告
返信 削除キー/


Mode/  Pass/


- Child Tree -