質問者
データバインドについてご質問です;

質問
-
いつもお世話になっております。
データソースコントロールを使わず、SQLCommandにて接続をしています。
SelectCommand のWhere句パラメータ に 配列変数を使用し、以下の様に繰り返しをさせた場合、全ての結果を一つのGridviewへbaindさせる方法はありますでしょうか?
For i =0 to 5
Dim cmd As New SqlCommand("SELECT xxxx,xxxx,xxxx FROM xxxx WHERE (ccc = '" & TMP(i) & "') ", db)
reader = cmd.ExecuteReader()
While reader.ReadMe.GridView3.DataSource = reader
Me.GridView3.DataBind()End While
i = i + 1
reader.Close()next
このままでは最後i=5 でのSelectCommand の結果のみバインドされています;;
アドバイスお願い申し上げます。
すべての返信
-
まず、SELECT 文が最悪。
なぜ TMP が配列である必要があるのですか?
配列だろうと、WHERE のところを OR で条件を指定すればよいですし、配列や SELECT の構文をそのまま生かした形であれば、UNION で結合した 1 つの SQL として実行するのが本筋でしょう。
あと WHERE の条件を直接入れるのではなくパラメータ化して実行するのが良いでしょう。この状態をなるべく変えたくないのなら、DataSet と SqlDataAdapter を使って全 SELECT 結果を DataSet の DataTable に格納して DataSource として DataBind をするのがいいのでは?
-
こんばんは^^v
おがわみつぎ さん レスありがとうございます。
Select文でなぜ配列を使うのか?という点ですが、Parameters.addの使い方が今一理解できてなくて;;・・配列にした次第です><
○日で覚える・・ を買って読んで見たのですが・・、Parameters.add・・・理解出来なかった;;
さて、質問した件ですが、
DataAdapterを始めて使ってみました。
Dim dataSet As New DataSet()
For i = 0 To 1
Dim cmd As New SqlCommand("SELECT xxxx,xxxx,xxxx,xxxx, FROM [CCCC] WHERE ([xxxx] = '" & tmp(i) & "')", db)Dim dataAdapter As New SqlDataAdapter(cmd)
Dim dataSet As New DataSet()
dataAdapter.Fill(dataSet, "CCCC")Me.GridView1.DataSource = New DataView(dataSet.Tables(0))
Next
Me.GridView1.DataBind()
db.Close()質問上げる前に、一度DataAdapter 試してみたのですが、やはり配列最後のSelect文に対応する結果しか取れなくて・・・
その時は、赤字部分にdatasetの宣言を書いてまして ループする度に毎回Datasetが初期化作成されて・・Tables(0)の内容もループ毎に初期化されてるdatasetに対してTables作成って訳だったのですね;;
よろしければ、Parameters作成・値設定 など アドバイス頂ければと思います。
-
もし、仮にparametersを使うとしたら、
Dim cmd As New SqlCommand("SELECT xxxx,xxxx,xxxx,xxxx, FROM [CCCC] WHERE ([xxxx] = @temp", db)
のようにしておいて(SQL文で、パラメータ部分を文字列連結で作成していないところに注意して下さい)、
cmd.Parameters.Clear() '要らないと思うけど、一応クリア
cmd.Parameters.Add("@temp", SqlDbType.Int)For i=0 To 5
cmd.Parameters("@temp").Value = temp(i)
dataAdapter.Fill(dataSet, "CCCC")
Nextのような感じになります。(上記コードは空で書いているので、微妙に違っているかもしれません)
Fillはデータをデータテーブルに追加しますから、Fillを繰り返した分のデータが、データテーブルに格納されます。
なので、動作的にはうまく行くと思いますが、効率は非常に悪いです。プログラムからSQL文を発行する回数は、一般的に、少なければ少ない方が効率的です。できれば、一度のSQL文で、まとめてデータを取得したいところです。SQL文を工夫してみましょう。 -
trapemiya さん こんばんわ^^v
いつも 判りやすい コード + 初心者用に噛み砕いて下さった アドバイスありがとうございます。
これくらい噛み砕いて頂けると 初心者の私でも 発見につなげやすいです^^v
配列を使わず、 仮に50個の条件を一回のSQLコマンドで Union ならびに orで 書くのって労力すごいいりそう・・・;;
1~∞ ってありえないですが、Where ○○ =@xxx の パラメーターにセットされる値数が 上限想定できない場合でも一回のSQL発行で取得可能・・・・。
ループ処理だと何度も発行されるし・・・・。
Where句の 後の パラメータ箇所を ループで ”or” & ” (○○=@xxx)” で ループ数分連結させ、最後に SQLCommandへ合体なのかなぁ・・・。
でも、それだと@xxx は同じ名前のまま・・インデックスも指定してないし・・このままでは 50個 or連結できても 値はループ最後の値が50個はいる事になりそうですね;;
今いる場所ではvwdが入ってなく 検証が出来ないので 明日チャレンジしたいと思います。
-
ナウシカ さんからの引用
Where句の 後の パラメータ箇所を ループで ”or” & ” (○○=@xxx)” で ループ数分連結させ、最後に SQLCommandへ合体なのかなぁ・・・。
はい、それしかありません。例えば、検索キーワードを空白で区切って指定される場合、いくつあるかわかりませんし、それはorなりandなりで繋いでいくしかありません。ナウシカ さんからの引用
でも、それだと@xxx は同じ名前のまま・・インデックスも指定してないし・・このままでは 50個 or連結できても 値はループ最後の値が50個はいる事になりそうですね;;
パラメータは文字列ですので、ループで回す時に○○=@xxx + i.ToString()
のようにしてしまえば良いと思います。