こんにちは^^よろしくお願いします。
■環境
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が主キーです。
答えでなくて申し訳ないですが(俺は DB プログラミングに疎いので答えは知らないのですが)、DBGridView というのは何者ですか?
.NET Framework 標準の DataGridView ですか? ならば DataGridView と書きましょう。
そうでない、サードパーティのコントロールを使っているなら、どこのコントロールなのか書きましょう。
>aetos様
ご指摘の通りです。
DBGridViewではなく標準のDataGridViewでした。
『同時実行違反』というキーワードで調べればたくさん情報が
引っ掛かると思います。
http://madia.world.coocan.jp/cgi-bin/VBBBS2/wwwlng.cgi?print+200503/05030080.txt
とりあえず UpdateCommand の CommandText を自分で作成して調査してみてください。
・商品テーブルに、主キーは含まれていますか?
・商品テーブルの、各列のデータ型は何ですか?
・OleDbCommandBuilder によって、OleDbDataAdapter 内に自動生成された SQL は、どのような物ですか?
DataGridView1(更新後テーブル)、 "DT商品"(更新前テーブル)
なので更新は1件もされないので、
処理予定の 1 レコードのうち 0 件が処理されました。のエラーが出る
と思われます。
dSet.Tables(0)=DataGridView1.DataSource
で更新後をテーブルに戻せばいいかと?
DataSourceChangedのイベントで更新があった時
判定フラグを持てばいいかと?
>DataGridView1(更新後テーブル)、 "DT商品"(更新前テーブル)
>なので更新は1件もされないので、
DataSource に設定されているオブジェクトと DataGridView は連動してますし、
DataTable のテーブル名はローカルで勝手に付けられるものなので、
質問時のコードだけでも更新は可能なのでは?
実際、VB2005 Access2003 の環境で成功しました。
皆様の情報ありがとうございます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を自前で書くしかないのでしょうかねぇ?;;
>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
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にすればいいのでは?
http://madia.world.coocan.jp/cgi-bin/VBBBS2/wwwlng.cgi?print+200810/08100005.txt
フィールド名に"NO"を指定しているとだめって話が。
予約語だから?
どうもこんばんわ^^
あ様、特攻隊長まるるう様ありがとうございます。
どうやら特攻隊長まるるう様のおっしゃるように
”データベースのテーブル名”に使用してはいけない名前があり、
それらを使用していたためにうまく更新されず、
エラーとなってしまったということだと思います。
また、実際に”No”から”tbl_No”に変更したことにより
問題なく動作したことを確認できました!!
これからは気をつけたいと思います・・・w
皆様、本当にありがとうございました。
どうもお騒がせしましたm__m
ツイート | ![]() |