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

実行時にUpdateCommandのパラメーターに値をセットする方法

環境/言語:[Windows7 VB2010 SQLServer2008]
分類:[.NET]

義雄と申します。
とある掲示板に質問を致しました。
http://oshiete.goo.ne.jp/qa/7702747.html

頂いた回答に一時は納得したのですがどうにも解せません。
こちらで再質問させて下さい。
マルチポスト規定に当たるのであれば削除致します。

' -------------------------- ここから --------------------------------
データベースの更新についてご指導下さい。
VB2010からSQLサーバーのデータベースに接続しております。
dataAdapter.Updateによりデータベースを更新する際の
パラメーターへ値をセットする方法を教えて下さい。

テーブル名Test
Code Name
------------
A   Suzuki

希望する処理
テキストボックスに入力された名前に変更
例) Suzuki → Yamada

○フォームの変数として定義
Dim dataAdapter As New SqlDataAdapter
Dim dataSet As New DataSet

○FormLoad時にSelectCommandとUpdateCommandを設定
Dim SQL As String = ""
Dim command As SqlCommand
Dim connection As SqlConnection = New SqlConnection(〜)

SQL = "SELECT * FROM Test WHERE Code = @code "
command = New SqlCommand(SQL, connection)
dataAdapter.SelectCommand = command
dataAdapter.SelectCommand.Parameters.Add("@code", SqlDbType.Char)

SQL = "UPDATE Test SET Name = @name WHERE Code = @code"
command = New SqlCommand(SQL, connection)
dataAdapter.UpdateCommand = command
dataAdapter.UpdateCommand.Parameters.Add("@code", SqlDbType.Char)
dataAdapter.UpdateCommand.Parameters.Add("@name", SqlDbType.Text, 50)

○データ表示時にはこれで表示されました。
dataAdapter.SelectCommand.Parameters.Item("@code").Value = ComboBoxCode.text
dataAdapter.Fill(dataSet)

○このSelectCommandを参考にこのように書いて見たのですが更新されません。
dataAdapter.UpdateCommand.Parameters.Item("@code").Value = ComboBoxCode.Text
dataAdapter.UpdateCommand.Parameters.Item("@name").Value = TextBoxName.Text
dataAdapter.Update(dataSet)

どのようにしたら実行時にパラメーター化したところへデータをセットできるのでしょうか?
データセットに値が入っていないのでは?と予想したのですが…。
' -------------------------- ここまで --------------------------------

その後、更にサイト検索を行い、やはりパラメーターにセットできるのではないか?
と思い始めました。これらがそう思ったサイトです。

http://msdn.microsoft.com/ja-jp/library/system.data.sqlclient.sqldataadapter.insertcommand.aspx
http://msdn.microsoft.com/ja-jp/library/vstudio/bbw6zyha(v=vs.90).aspx

エラーや例外が出ず、dataAdapter.Update(dataSet)の値も0です。
どのようにしたら実行時にパラメータの値にセットできるのでしょうか。
現状では直接SQL文をExecuteNonQueryで発行しております。
dataAdapter.Update(dataSet)

command.Connection = connection
connection.Open()
Dim cnt As Integer = command.ExecuteNonQuery()
connection.Close()
としたら更新出来ました。
取得の方は・・・
Using OraDB As OracleConnection = New OracleConnection(GetDBConnectString())
Try
OraDB.Open
bRet = True
Catch ex as Exception
bRet = False
End Try
If bRet Then
Using OraAD As OracleDataAdapter = New OracleDataAdapter
Using OraCmd As OracleCommand = New OracleCommand("select * from xxxxxxxxxx", OraDB)
With OraCmd
.CommandType = CommandType.Text
.CommandTimeout = OraDB.ConnectionTimeout
.CommandText = oraSQL.ToString
End With

OraAD.SelectCommand = OraCmd

Try
iRet = OraAD.Fill(TraIdTable)
bRet = True
Catch ex as Exception
bRet = False
End Try
If bRet AndAlso iRet > 0 Then
BindingSource1.DataSource = TraIdTable
Else
BindingSource1.DataSource = Nothing
End If
End Using
End Using

OraDB.Close

End If
End Using

更新の方は・・・
Using OraDB As OracleConnection = New OracleConnection(GetDBConnectString())
Try
OraDB.Open
bRet = True
Catch ex as Exception
bRet = False
End Try
If bRet Then
Using OraAD As OracleDataAdapter = New OracleDataAdapter
OraAD.SelectCommand = New OracleCommand("select * from xxxxxxxxxx", OraDB)
Using cb As OracleCommandBuilder = New OracleCommandBuilder(OraAD)
Try
iRet = OraAD.Update(CType(BindingSource.DataSource, DataTable))
bRet = True
Catch ex As Exception
bRet = False
iRet = 0
End Try
End Using
End Using

OraDB.Close

End If
End Using

こんなコードで、ピンときて頂けたら幸いです。

※ 取得したデータを、BindingSource.DataSource に格納し
  DataGridView に表示させて編集・削除させ・・・
  後、本来のデータベース側を更新させます。

※ ODP.NET使ってますが、基本ADO.NETを派生されたものです
  ので、SQL Server用には、すぐに変更可能ですヨ!


以上。参考まで
パラメータの設定は・・・抜けてましたネ・・・すいません。

基本は、あなたの書いたコードで更新できます。
理由は、取得時と更新時のDataAdapterを生成する部分が、
同じデータを取得するSelectCommandとなっているでしょう

以上。
申し訳ございません。恥を忍んでお願いがあります。
今一度ご指導をお願いしたく思います。

先ほど、解決済みにしてしまいましたが私の間違いでした。
先ほどプログラムが動いたのは私の「■30951 / inTopicNo.2」の発言にある

command.Connection = connection
connection.Open()
Dim cnt As Integer = command.ExecuteNonQuery()
connection.Close()

が挿入されたままであるのを気付かずに「動いた」と勘違いしてしまいました。
顔から火がでる思いです。
オショウ様、みなさま申し訳ありません。

このトピックの「解決済み」を取りやめる為、最後の書き込みは削除いたしました。


http://msdn.microsoft.com/ja-jp/library/system.data.sqlclient.sqldataadapter.insertcommand.aspx
や、いろいろなサイトを参考に、DataAdapterを作成致しました。

Public Function DataAdapterCreate() As SqlDataAdapter
  Dim SQL As String = ""
  Dim connection As SqlConnection = New SqlConnection(接続文字列)

  SQL = "SELECT * FROM Test WHERE Code = @code"
  dataAdapter.SelectCommand = New SqlCommand(SQL, connection)
  dataAdapter.SelectCommand.Parameters.Add("@code", SqlDbType.Char)

  SQL = "UPDATE Test SET Name = @name WHERE Code = @code"
  dataAdapter.UpdateCommand = New SqlCommand(SQL, connection)
  dataAdapter.UpdateCommand.Parameters.Add("@code", SqlDbType.Char)
  dataAdapter.UpdateCommand.Parameters.Add("@name", SqlDbType.Text)

  Return dataAdapter
End Function

○データ表示時にはこれで表示されます。
dataAdapter.SelectCommand.Parameters.Item("@code").Value = ComboBoxCode.text
dataAdapter.Fill(dataSet)

○このSelectCommandを参考にこのように書いて見たのですが更新されません。
dataAdapter.UpdateCommand.Parameters.Item("@code").Value = ComboBoxCode.Text
dataAdapter.UpdateCommand.Parameters.Item("@name").Value = TextBoxName.Text
dataAdapter.Update(dataSet)

SelectCommandとUpdateCommandを分けて実行してみても結果は同じでした。

DataGridViewを利用してのまとめての更新や、SQLを直接発行させる方法では更新できます。
テキストボックスやコンボボックスを使って1レコードずつの更新が出来ずにハマっております。
1レコードずつの方がはるかに簡単なのでは?と高を括った罰があたってしまいました…。

なにか根本的な思い違いをしているのでしょうか。

今一度、ご指導のほどよろしくお願いいたします。
■No30957に返信(義雄さんの記事)

> dataAdapter.UpdateCommand.Parameters.Add("@code", SqlDbType.Char)
ソース列を指定しましょう。
dataAdapter.UpdateCommand.Parameters.Add("@code", SqlDbType.Char,5,"code")
とするとdatatableのcode列と関連付けられます。


> dataAdapter.UpdateCommand.Parameters.Item("@code").Value = ComboBoxCode.Text
> dataAdapter.UpdateCommand.Parameters.Item("@name").Value = TextBoxName.Text
> dataAdapter.Update(dataSet)
ではなく
対象となるDataTableのDataRowを編集してUpdateしましょう。
Dim Tbl = dataset.Tables(0)   '--- 適当に合わせてください
Dim Rows = Tbl.Select(String.Format("code = '{0}'",ComboBoxCode.Text))
Dim Row As DataRow

If Rows.Count=0 Then
    Row = Tbl.NewRow
    Row("code") = ComboBoxCode.Text
    Tbl.Rows.Add(Row)
Else
    Row = Rows(0)
End If
Row("name") = TextBoxName.Text

dataAdapter.Update(dataSet)
'dataAdapter.Update(Tbl)でも可
shuさま、ご指導ありがとうございます。

このようにして使えばいいのですね。すんなり更新出来ました。
今度こそ大丈夫です!本当にありがとうございました。
解決済み!

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