2006年09月21日

Parameters の使用上の注意(ADO.NET)

SQLステートメントでパラメータを使用する場合にParametersプロパティに値をセットするが、連続してSQLを実行する場合、事前にパラメータの内容を消しておかないと同じ内容で処理されてしまうので注意する。
最初これに気が付かず、何故エラーするのか大いに迷ったことがある。

(Dim cmd As New OleDbCommand)
 
For i = 0 To 2
With Item(i)
cmd.CommandText = "insert into hoge_tb values(?,?,?)"
cmd.Parameters.Clear() 'これが無いとItem(0)の内容が3回登録されてしまう。
cmd.Parameters.Add("id", OleDbType.Integer).Value = .id
cmd.Parameters.Add("no", OleDbType.SmallInt).Value = i
cmd.Parameters.Add("namae", OleDbType.VarWChar).Value = .Name
cmd.ExecuteNonQuery()
End With
Next i

posted by なっちゃん at 14:44| 静岡 ????| Comment(8) | TrackBack(0) | VB.NET Tips | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
今回のようなコードの場合、cmdをループの外で作成しているのならCommandTextとParametersの中身はループの外で作っておくべきでしょう。
ループの中では
cmd.Parameters(0).Value = .id
で値を設定します
それとAddした返り値オブジェクトに直接Valueを設定する書き方はどうかと思います。値を一緒に設定するなら別のAddを使うべきです。

文のパラメータより多い数のパラメータがあってもエラーが出なかったり同じパラメータ名を複数設定できてしまう仕様は微妙だと思いますが。
Posted by ほいほい at 2006年09月29日 15:39
仰る事の半分は判りますが、もう半分は理解できません。それと言うのもまだ使い方が判ってない部分があるからです。
Parameters.Add(xxx).value = yyyy はヘルプにもある使い方で、これが問題だという理由が判りません。
Posted by なっちゃん at 2006年09月29日 16:02
ほんとですか。そういうヘルプは私は見たことがないですね。

私がこれを問題だと思うのはコレクションへの
追加とその追加したアイテムへの操作を同時に
行っているからです。
2つのレベルの違うオブジェクトにつながり
のない別の操作をしているのが問題だと感じます。

Parameters.Add(xxx).value = yyyy
と書くなら
しかるべきアイテムを作成してから追加
Parameters.Add(New Parameter(xxx, yyyy
))
または
ただ追加した後、値を設定する
Parameters.Add(xxx, type)
Parameters(xxx).Value = yyyy
とでもすべきではということです。
Posted by ほいほい at 2006年09月29日 18:51
では、サンプルが掲載されているヘルプの場所を書いておきます。

ms-help://MS.VSCC.v80/MS.MSDN.v80/
MS.NETDEVFX.v20.ja/cpref4/html/
T_System_Data_OleDb_OleDbParameter.htm

ここに、

adapter.SelectCommand.Parameters.Add( _
"@CategoryName", OleDbType.VarChar, 80).Value = "toasters"

adapter.SelectCommand.Parameters.Add( _
"@SerialNum", OleDbType.Integer).Value = 239

という記述があります。
Posted by なっちゃん at 2006年09月29日 19:32
本当ですね。気づきませんでした。
でもたとえマイクロソフトのサンプルでも私はこのような書き方を薦めません。
前発言のような書き方を薦めます。
Posted by ほいほい at 2006年10月02日 18:23
古い記事へのコメントをご容赦ください。

こういう書き方は一般的に許されるべきだと思いますよ。
Addメソッドの戻り値がなぜこの型なのか?を考えると、まさにこういった使い方を想定しているからだと思いませんか?

VB系ではこういう書き方はあまりなじみが無いのかもしれませんが、他の言語では過去から良く使われる手法だと思います。
Posted by ざうたけ at 2008年02月13日 09:59
「よく使われる手法」というのは何かを混同されてると思います。

Addメソッドは文字通りパラメータを"追加"するわけですから、ループの中で使用するのはダメです。

例えば10万件のデータをInsertする用途で上記のコードを使用したらOut of Memoryになりますよ。
Posted by 通りすがり at 2008年07月11日 19:04
Out of Memory にはならないです。
Parameters.Clear() してますから。
Posted by なっちゃん at 2008年07月11日 19:33
コメントを書く
お名前: [必須入力]

メールアドレス:

ホームページアドレス:

コメント: [必須入力]

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
この記事へのトラックバックURL
http://blog.seesaa.jp/tb/24141156
※言及リンクのないトラックバックは受信されません。

この記事へのトラックバック