- ベストアンサー
.net データベースへ反映する方法
- <環境> 言語:Microsoft Visual Studio 2008 データベース:SQL Server 2005 非接続型のデータアクセスです。 以前同じ質問をさせていただいたのですが、解決できなかったため、再度投稿させていただきました。
- <質問> DataGridViewにデータを表示し、登録、修正、削除を行った後、更新ボタンを押下でDataGridViewの内容をデータベース(SQLServer)に反映したいのですが、エラーとなり反映できません。http://japan.internet.com/developer/20070522/26.htmlを参考にしているのですが、四苦八苦。全然前に進めない状態です。自作したコードを下記の通りです。いったいどこを直せばよろしいでしょうか?どなたかアドバイスよろしくお願いします。
- <エラー>---------------------------------------------------------- "System.ArgumentNullException: 値を Null にすることはできません。 パラメータ名: dataTable 場所 System.Data.Common.DbDataAdapter.Update(DataTable dataTable) -------------------------------------------------------------------- Private Sub frmDataGridViewTest_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load Dim strsql As String Call DBConnect() 'DB接続 strsql = "SELECT ID, 名称, 型式 FROM ATBL ORDER BY ID" Dim comm As SqlCommand = New SqlCommand(strsql, Con) Dim dataadapter As SqlDataAdapter = New SqlDataAdapter(comm) dataadapter.MissingSchemaAction = MissingSchemaAction.AddWithKey Dim ds As DataSet = New DataSet() dataadapter.Fill(ds, "テーブル") dgrview.DataSource = ds dgrview.DataMember = "テーブル" Call Disconnect() 'DB切断' End Sub Private Sub BTN_更新_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BTN_更新.Click Dim strsql As String Call DBConnect() 'DB接続 strsql = "SELECT ID, 名称, 型式 FROM ATBL ORDER BY ID" Dim comm As SqlCommand = New SqlCommand(strsql, Con) Dim dataadapter As SqlDataAdapter = New SqlDataAdapter(comm) dataadapter.MissingSchemaAction = MissingSchemaAction.AddWithKey dataadapter.Fill(ds, "テーブル") Dim dt As DataTable = ds.Tables("テーブル") '<<<DataGridViewコントロールでの変更をデータベースに戻す>>> Dim sqlCmdBuilder As New SqlCommandBuilder(dataadapter) sqlCmdBuilder.GetUpdateCommand() dataadapter.Update(ds.Tables("テーブル")) Call Disconnect() 'DB切断' End Sub
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
どうもそのリレーションが原因のようです MSDNの『コマンドの自動生成』 ms-help://MS.MSDNQTR.v80.ja/MS.MSDN.v80/MS.VisualStudio.v80.ja/WD_ADONET/html/6e3fb8b5-373b-4f9e-ab03-a22693df8e91.htm ページから引用 コマンドの自動生成には次の制限事項が適用されます。 リレーションシップのないテーブルに限定 コマンドの自動生成ロジックでは、データ ソースの他のテーブルへのリレーションシップを考慮せずに、独立したテーブルを対象として INSERT、UPDATE、または DELETE の各ステートメントを生成します。その結果、Update を呼び出してデータベースの外部キー制約に関係する列に対する変更を発行すると、エラーが発生する場合があります。このような例外を防ぐには、外部キー制約に関係する列の更新には DbCommandBuilder を使用せず、更新操作を実行するステートメントを明示的に指定します。 --- ここまで といった具合の記述があります ためしに別プロジェクトで接続型のDataBindingSourceを使うやり方でUpdateやInsert,Deleteコマンドを自動生成してくれるか試してみてください
その他の回答 (2)
- redfox63
- ベストアンサー率71% (1325/1856)
Dim ds As DataSet = New DataSet() ds = CType(dgrview.DataSource, DataSet) Dim sqlCmdBuilder As New SqlCommandBuilder(dataadapter) sqlCmdBuilder.GetUpdateCommand() dataadapter.UpdateCommand = sqlCmdBuilder.GetUpdateCommand() dataadapter.Update(ds.Tables("テーブル")) の部分は Dim ds As DataSet' 不要 = New DataSet() dim dt as DataTable ' 追加 ds = CType(dgrview.DataSource, DataSet) Dim sqlCmdBuilder As New SqlCommandBuilder(dataadapter) ' 不要 sqlCmdBuilder.GetUpdateCommand() dataadapter.UpdateCommand = sqlCmdBuilder.GetUpdateCommand() dt = ds.Tables("テーブル") if dt is nothing then msgbox("テーブル異常") exit sub end if ' 変更 dataadapter.Update(ds.Tables("テーブル")) dataadapter.Update( dt ) のようにしてみましょう これでメッセージボックスが表示されるようなら DataSet内のテーブルの指定がおかしいことになります
お礼
何度もありがとうございます。 教えていただいたコードで実行してみましたがエラーになりました。 dataadapter.UpdateCommand = sqlCmdBuilder.GetUpdateCommand() のところで下記のエラーです。 System.InvalidOperationException: ConnectionString プロパティは初期化されていません。 原因がわからないのですが、一つ気になる点が… 質問では簡潔に書きたかったため、SQL文をリンクなしにしていました。本当は、こんな感じなんです。 SELECT ID, 名称, 型式, BTBL.メーカー名 FROM ATBL LEFT OUTER JOIN BTBL ON ATBL.コード = BTBL.コード これが原因でしょうか?
- redfox63
- ベストアンサー率71% (1325/1856)
sqlCmdBuilderのGetUpdateCommandで取得したsqlCommandオブジェクトを dataadapter.UpdateCommandで代入していないの原因です dataadapter.UpdateCommand = sqlCmdBuilder.GetUpdateCommand() 編集後のデータは ds = CType( dgrview.DataSource, DataSet ) でいいように思います わざわざデータベースから更新前のデータを取得する必要はないでしょう
補足
早々のお返事ありがとうございます。 更新ボタン押下時をこのように直したのですが、ピント違いでしょうか?これですとまだ同様のエラーが出てしまいます。 Private Sub BTN_更新_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BTN_更新.Click Dim strsql As String Call DBConnect() 'DB接続 strsql = "SELECT ID, 名称, 型式 FROM ATBL ORDER BY ID" Dim comm As SqlCommand = New SqlCommand(strsql, Con) Dim dataadapter As SqlDataAdapter = New SqlDataAdapter(comm) Dim ds As DataSet = New DataSet() ds = CType(dgrview.DataSource, DataSet) Dim sqlCmdBuilder As New SqlCommandBuilder(dataadapter) sqlCmdBuilder.GetUpdateCommand() dataadapter.UpdateCommand = sqlCmdBuilder.GetUpdateCommand() dataadapter.Update(ds.Tables("テーブル")) Call Disconnect() 'DB切断 End Sub
お礼
確かに。確認しました。 簡単にできそうだけど制限があったんですね。 結局、更新はRowStateで判定して更新処理を行うようにしました。 初心者の私でもわかるように説明していただきありがとうございました。