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

  • 質問

  • いつもお世話になっております。

    データソースコントロールを使わず、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.Read

                            Me.GridView3.DataSource = reader
                            Me.GridView3.DataBind()

                        End While

                        i = i + 1
                        reader.Close()

    next  

     

    このままでは最後i=5 でのSelectCommand の結果のみバインドされています;;

    アドバイスお願い申し上げます。

    2007年1月31日 7:50

すべての返信

  • まず、SELECT 文が最悪。
    なぜ TMP が配列である必要があるのですか?
    配列だろうと、WHERE のところを OR で条件を指定すればよいですし、配列や SELECT の構文をそのまま生かした形であれば、UNION で結合した 1 つの SQL として実行するのが本筋でしょう。
    あと WHERE の条件を直接入れるのではなくパラメータ化して実行するのが良いでしょう。

    この状態をなるべく変えたくないのなら、DataSet と SqlDataAdapter を使って全 SELECT 結果を DataSet の DataTable に格納して DataSource として DataBind をするのがいいのでは?

    2007年1月31日 8:23
  • こんばんは^^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作成・値設定 など アドバイス頂ければと思います。

     

     

     

    2007年1月31日 13:06
  • もし、仮に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文を工夫してみましょう。

    2007年1月31日 15:20
    モデレータ
  • trapemiya さん こんばんわ^^v

    いつも 判りやすい コード + 初心者用に噛み砕いて下さった アドバイスありがとうございます。

    これくらい噛み砕いて頂けると 初心者の私でも 発見につなげやすいです^^v

    配列を使わず、 仮に50個の条件を一回のSQLコマンドで Union ならびに orで 書くのって労力すごいいりそう・・・;;

    1~∞ ってありえないですが、Where ○○ =@xxx の パラメーターにセットされる値数が 上限想定できない場合でも一回のSQL発行で取得可能・・・・。

    ループ処理だと何度も発行されるし・・・・。

    Where句の 後の パラメータ箇所を ループで ”or” & ” (○○=@xxx)” で ループ数分連結させ、最後に SQLCommandへ合体なのかなぁ・・・。

    でも、それだと@xxx は同じ名前のまま・・インデックスも指定してないし・・このままでは 50個 or連結できても 値はループ最後の値が50個はいる事になりそうですね;;

     

    今いる場所ではvwdが入ってなく 検証が出来ないので 明日チャレンジしたいと思います。

     

     

     

     

     

    2007年2月1日 14:39
  •  ナウシカ さんからの引用

    Where句の 後の パラメータ箇所を ループで ”or” & ” (○○=@xxx)” で ループ数分連結させ、最後に SQLCommandへ合体なのかなぁ・・・。

    はい、それしかありません。例えば、検索キーワードを空白で区切って指定される場合、いくつあるかわかりませんし、それはorなりandなりで繋いでいくしかありません。

     ナウシカ さんからの引用

    でも、それだと@xxx は同じ名前のまま・・インデックスも指定してないし・・このままでは 50個 or連結できても 値はループ最後の値が50個はいる事になりそうですね;;

    パラメータは文字列ですので、ループで回す時に

    ○○=@xxx + i.ToString()

    のようにしてしまえば良いと思います。 

    2007年2月2日 3:30
    モデレータ