DBGridView+ADO.NETを使用した更新処理

解決


タイガー  2008-10-01 22:21:01  No: 145253

こんにちは^^よろしくお願いします。

■環境
OS:XP SP3
開発環境:VSDE2008(SP1)のVB2008
.NET Framework:3.0
データベース:Access2003で作成

■概要
プロジェクト作成後、フォームにDBGridViewとボタン1つを貼り付けた状態です。
起動時に、DBGridView1にデータベースの内容を表示します。
データを編集後、ボタンを押すとデータベースに更新を適用させるというプログラムです。

■問題点
例えば、ID1のNameの"あ"を"1"に変更して、更新処理を行うと
”同時実行違反 : UpdateCommand によって、処理予定の 1 レコードのうち 0 件が処理されました。”
というエラーが発生してしまいます。
また、データベースの内容を変更していくつか試しましたが、よくわからない状況です。
おそらくデータベースの方に問題があるかのように予想してます。
設定やデータベース作成のルールなどがあるのでしょうか?

■コード
Public Class Form1
    Dim dSet As New DataSet
    Dim dAdp As OleDb.OleDbDataAdapter

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        Dim cn As New OleDb.OleDbConnection
        cn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\DATA\all.mdb"
        dAdp = New OleDb.OleDbDataAdapter("SELECT * FROM 商品", cn)
        dAdp.Fill(dSet, "DT商品")
        DataGridView1.DataSource = dSet.Tables("DT商品")

    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        DataGridView1.EndEdit()
        Dim cBld = New OleDb.OleDbCommandBuilder(dAdp)
        dAdp.Update(dSet, "DT商品")

    End Sub
End Class

■データベースファイル
all.mdb
商品テーブル
ID Name 
1 あ
2 い
3 う

IDが主キーです。


aetos  2008-10-02 00:42:40  No: 145254

答えでなくて申し訳ないですが(俺は DB プログラミングに疎いので答えは知らないのですが)、DBGridView というのは何者ですか?
.NET Framework 標準の DataGridView ですか?  ならば DataGridView と書きましょう。
そうでない、サードパーティのコントロールを使っているなら、どこのコントロールなのか書きましょう。


タイガー  2008-10-02 01:17:42  No: 145255

>aetos様
ご指摘の通りです。
DBGridViewではなく標準のDataGridViewでした。


特攻隊長まるるう  2008-10-02 02:38:07  No: 145256

『同時実行違反』というキーワードで調べればたくさん情報が
引っ掛かると思います。

http://madia.world.coocan.jp/cgi-bin/VBBBS2/wwwlng.cgi?print+200503/05030080.txt
とりあえず UpdateCommand の CommandText を自分で作成して調査してみてください。


魔界の仮面弁士  2008-10-02 02:38:18  No: 145257

・商品テーブルに、主キーは含まれていますか?
・商品テーブルの、各列のデータ型は何ですか?
・OleDbCommandBuilder によって、OleDbDataAdapter 内に自動生成された SQL は、どのような物ですか?


  2008-10-02 08:52:51  No: 145258

DataGridView1(更新後テーブル)、 "DT商品"(更新前テーブル)
なので更新は1件もされないので、
処理予定の 1 レコードのうち 0 件が処理されました。のエラーが出る
と思われます。
dSet.Tables(0)=DataGridView1.DataSource 
で更新後をテーブルに戻せばいいかと?
DataSourceChangedのイベントで更新があった時
判定フラグを持てばいいかと?


特攻隊長まるるう  2008-10-02 20:10:04  No: 145259

>DataGridView1(更新後テーブル)、 "DT商品"(更新前テーブル)
>なので更新は1件もされないので、
DataSource に設定されているオブジェクトと DataGridView は連動してますし、
DataTable のテーブル名はローカルで勝手に付けられるものなので、
質問時のコードだけでも更新は可能なのでは?

実際、VB2005 Access2003 の環境で成功しました。


タイガー  2008-10-03 04:28:42  No: 145260

皆様の情報ありがとうございますm__m
遅くなりましたがご報告します。

>特攻隊長まるるう 様
>http://madia.world.coocan.jp/cgi-bin/VBBBS2/wwwlng.cgi?print+200503/05030080.txt
>とりあえず UpdateCommand の CommandText を自分で作成して調査してみてください。
検索サイトで調べてみても、UpdateCommandを自作するような内容が多かったです。
ですが、自動的にSQLを作成してくれる(と認識してますw)OleDbCommandBuilderは万能じゃないってことですかねぇ・・・?

>実際、VB2005 Access2003 の環境で成功しました。
実際に実行していただきまして、恐れ入ります。
もしかしたらVBの問題ではなくデータベース側かもしれませんね・・・
当方でも引き続き調査してみます。

>あ  様
安直ですが、教えていただいた内容をButton1_Clickイベントに以下のようにして実行させようとしましたが、
当方の環境では、”プロパティ'Item'は'ReadOnly'です。”とエラーが発生してしまって実行できませんでした。

■そのときのコード
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        DataGridView1.EndEdit()
        dSet.Tables(0) = DataGridView1.DataSource

    End Sub

また、dSet.Tables(0)をdSet.Tables("DT商品")に変更してみましたが同様のエラーでした。
引き続き調べてみますが、ご助言いただけるとありがたいです。

>魔界の仮面弁士 様
ありがとうございます。以下、いかがでしょうか?

■データベース詳細
ファイル名:all.mdb
テーブル名:商品
No:数値型(主キー)
Name:テキスト型
備考:アクセス2003で新規作成し、
”デザインビューでテーブルを作成する”より
上記を設定後、データを入力しました(その他の設定値はデフォルトのままです)。

■OleDbDataAdapterのSQL値
No1のName行を1に変更した後、更新処理させている箇所の
dAdp.Update行で実際ウォッチした内容です。

DeleteCommand=Nothing
SelectCommand.CommandText="SELECT * FROM 商品"
UpdateCommand=Nothing

*おそらくUpdateCommandがNothingとなっているので、
CommandBuilderが更新SQLを作成できなかったためにエラーとなるのかなぁと感じました。
そうなってくると当方のOleDbCommandBuilderの使い方が悪いのか、
はたまたUpdateCommandを自前で書くしかないのでしょうかねぇ?;;


特攻隊長まるるう  2008-10-03 05:22:34  No: 145261

>DeleteCommand=Nothing
>SelectCommand.CommandText="SELECT * FROM 商品"
>UpdateCommand=Nothing
…あれ。。。こっちの環境[VB2005 Express Edition]でも
同じ結果に。。。なんで更新されるんだろ(@@
テーブルに主キーの情報が取れてない状態でも更新できます。。。

怖いなぁ。。。

Public Class frm商品

    Dim dSet As New DataSet
    Dim dAdp As OleDb.OleDbDataAdapter

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        Dim cn As New OleDb.OleDbConnection
        'cn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\Database\all.mdb"
        cn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\DATA\all.mdb"
        '商品Table の構成  ID:数値型(主キー)※Noになっちゃった?
        '                  Name:   テキスト型
        dAdp = New OleDb.OleDbDataAdapter("SELECT * FROM 商品", cn)
        dAdp.MissingSchemaAction = MissingSchemaAction.AddWithKey
        dAdp.FillSchema(dSet, SchemaType.Source, "DT商品")
        dAdp.Fill(dSet, "DT商品")
        DataGridView1.DataSource = dSet.Tables("DT商品")

        Call GetPrimaryKeys(dSet.Tables("DT商品"))
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        '主キーの項目は変更せず、Name のみ DataGridView1 で入力して実行
        DataGridView1.EndEdit()
        Dim cBld As OleDb.OleDbCommandBuilder = New OleDb.OleDbCommandBuilder(dAdp)
        'Console.WriteLine(dAdp.UpdateCommand.CommandText) '←Nothingのエラー出ます(;;
        dAdp.Update(dSet, "DT商品")

    End Sub

    Private Sub GetPrimaryKeys(ByVal table As DataTable)
        ' Create the array for the columns.
        Dim columns() As DataColumn
        columns = table.PrimaryKey

        ' Get the number of elements in the array.
        Console.WriteLine("Column Count: " & columns.Length.ToString())
        Dim i As Integer
        For i = 0 To columns.GetUpperBound(0)
            Console.WriteLine(columns(i).ColumnName & ":" & columns(i).DataType.ToString())
        Next i
    End Sub
End Class


  2008-10-03 09:43:09  No: 145262

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        DataGridView1.EndEdit()
        dSet.Tables(0) = DataGridView1.DataSource
        Dim cBld = New OleDb.OleDbCommandBuilder(dAdp)
        dAdp.Update(dSet, "DT商品")
End Sub
プロパティ'Item'は'ReadOnly'です。”のエラーはDataGridView1の
カラムにReadOnly があるのでは?
すべてのカラムをFalseにすればいいのでは?


特攻隊長まるるう  2008-10-03 21:31:01  No: 145263

http://madia.world.coocan.jp/cgi-bin/VBBBS2/wwwlng.cgi?print+200810/08100005.txt
フィールド名に"NO"を指定しているとだめって話が。

予約語だから?


タイガー  2008-10-05 05:40:11  No: 145264

どうもこんばんわ^^

あ様、特攻隊長まるるう様ありがとうございます。
どうやら特攻隊長まるるう様のおっしゃるように
”データベースのテーブル名”に使用してはいけない名前があり、
それらを使用していたためにうまく更新されず、
エラーとなってしまったということだと思います。

また、実際に”No”から”tbl_No”に変更したことにより
問題なく動作したことを確認できました!!
これからは気をつけたいと思います・・・w
皆様、本当にありがとうございました。

どうもお騒がせしましたm__m


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加