none
GridViewにすべてのデータを表示させ、条件によって表示を変更させたいのですが RRS feed

  • 質問

  • GridViewに複数のテーブルをリレーションでまとめて作ったDataSet1.xsdを使い
    データベースの情報をすべて表示させ、
    TextBox1、TextBox2に条件が入った場合はその条件にあったものに
    絞り込めるGridViewを表示できるようにしたいのですがQUERYの書き方がよくわかりません。
    現時点ではDataSet1.xsdに項目(名前)と(クラス)のフィルタに【?】を入れて作ったQUERYを使ってみましたが
    実行するとTextBox1、TextBox2の情報が両方とも一致している場合のみしかGridViewが表示されません。

    どのようにしたら最初はすべてのデータを表示し、条件を入れた場合のみその条件にあうものが表示されるようになるのでしょうか?

    <%@ Page Language="VB" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <script runat="server">
    </script>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title>無題のページ</title>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
            名前<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
             クラス<asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>
             <asp:Button ID="Button1" runat="server" Text="検索" />
            <br />
            <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
                DataKeyNames="ID" DataSourceID="ObjectDataSource1">
                <Columns>
                    <asp:BoundField DataField="ID" HeaderText="ID" ReadOnly="True"
                        SortExpression="ID" />
                    <asp:BoundField DataField="名前" HeaderText="名前" SortExpression="名前" />
                    <asp:BoundField DataField="性別" HeaderText="性別" SortExpression="性別" />
                    <asp:BoundField DataField="クラス" HeaderText="クラス" SortExpression="クラス" />
                    <asp:BoundField DataField="国語" HeaderText="国語" SortExpression="国語" />
                    <asp:BoundField DataField="算数" HeaderText="算数" SortExpression="算数" />
                    <asp:BoundField DataField="社会" HeaderText="社会" SortExpression="社会" />
                    <asp:BoundField DataField="理科" HeaderText="理科" SortExpression="理科" />
                </Columns>
            </asp:GridView>
            <aspSurprisebjectDataSource ID="ObjectDataSource1" runat="server"
                OldValuesParameterFormatString="original_{0}" SelectMethod="GetDataBy"
                TypeName="DataSet1TableAdapters.DataTable1TableAdapter">
                <SelectParameters>
                    <asp:ControlParameter ControlID="TextBox1"  Name="Param1"
                        PropertyName="Text" Type="String" />
                    <asp:ControlParameter ControlID="TextBox2" Name="Param2"
                        PropertyName="Text" Type="String" />
                </SelectParameters>
            </aspSurprisebjectDataSource>
        </div>
        </form>
    </body>
    </html>

    2009年1月20日 14:35

回答

  •  komi1 さんからの引用

    GridViewに複数のテーブルをリレーションでまとめて作ったDataSet1.xsdを使い
    データベースの情報をすべて表示させ、
    TextBox1、TextBox2に条件が入った場合はその条件にあったものに
    絞り込めるGridViewを表示できるようにしたいのですがQUERYの書き方がよくわかりません。
    現時点ではDataSet1.xsdに項目(名前)と(クラス)のフィルタに【?】を入れて作ったQUERYを使ってみましたが
    実行するとTextBox1、TextBox2の情報が両方とも一致している場合のみしかGridViewが表示されません。

    どのようにしたら最初はすべてのデータを表示し、条件を入れた場合のみその条件にあうものが表示されるようになるのでしょうか?

     

    前回の例に倣って public partial class DataTable1TableAdapter を作って、例え
    ば GetDataBy(string name, string cls) というようなメソッドを作って、name と
    cls の値によって SELECT クエリを切り替えるようなコードを実装すれば実現でき
    ます。

     

    例えば、以下のような感じ。(コードは検証してませんので注意)

     

    Code Snippet

    string query;
    SqlDataAdapter adapter;

    if (name == String.Empty && cls == String.Empty)
    {
        query = "SELECT * FROM table";
        adapter = new SqlDataAdapter(query, this.Connection);
    }
    else if (name == String.Empty && cls != String.Empty)
    {
        query = "SELECT * FROM table WHERE cls=@cls";
        adapter = new SqlDataAdapter(query, this.Connection);
        adapter.SelectCommand.Parameters.AddWithValue("@cls", cls);
    }
    else if (name != String.Empty && cls == String.Empty)
    {
        query = "SELECT * FROM table WHERE name=@name";
        adapter = new SqlDataAdapter(query, this.Connection);
        adapter.SelectCommand.Parameters.AddWithValue("@name", name);
    }
    else
    {
        query = "SELECT * FROM table WHERE name=@name AND cls=@cls";
        adapter = new SqlDataAdapter(query, this.Connection);
        adapter.SelectCommand.Parameters.AddWithValue("@name", name);
        adapter.SelectCommand.Parameters.AddWithValue("@cls", cls);
    }

    XxxxxxDataSet dataset = new XxxxxxDataSet();
    adapter.Fill(dataset.Xxxxxx);
    return dataset.Xxxxxx;

     

     

    2009年1月20日 15:25

すべての返信

  •  komi1 さんからの引用

    GridViewに複数のテーブルをリレーションでまとめて作ったDataSet1.xsdを使い
    データベースの情報をすべて表示させ、
    TextBox1、TextBox2に条件が入った場合はその条件にあったものに
    絞り込めるGridViewを表示できるようにしたいのですがQUERYの書き方がよくわかりません。
    現時点ではDataSet1.xsdに項目(名前)と(クラス)のフィルタに【?】を入れて作ったQUERYを使ってみましたが
    実行するとTextBox1、TextBox2の情報が両方とも一致している場合のみしかGridViewが表示されません。

    どのようにしたら最初はすべてのデータを表示し、条件を入れた場合のみその条件にあうものが表示されるようになるのでしょうか?

     

    前回の例に倣って public partial class DataTable1TableAdapter を作って、例え
    ば GetDataBy(string name, string cls) というようなメソッドを作って、name と
    cls の値によって SELECT クエリを切り替えるようなコードを実装すれば実現でき
    ます。

     

    例えば、以下のような感じ。(コードは検証してませんので注意)

     

    Code Snippet

    string query;
    SqlDataAdapter adapter;

    if (name == String.Empty && cls == String.Empty)
    {
        query = "SELECT * FROM table";
        adapter = new SqlDataAdapter(query, this.Connection);
    }
    else if (name == String.Empty && cls != String.Empty)
    {
        query = "SELECT * FROM table WHERE cls=@cls";
        adapter = new SqlDataAdapter(query, this.Connection);
        adapter.SelectCommand.Parameters.AddWithValue("@cls", cls);
    }
    else if (name != String.Empty && cls == String.Empty)
    {
        query = "SELECT * FROM table WHERE name=@name";
        adapter = new SqlDataAdapter(query, this.Connection);
        adapter.SelectCommand.Parameters.AddWithValue("@name", name);
    }
    else
    {
        query = "SELECT * FROM table WHERE name=@name AND cls=@cls";
        adapter = new SqlDataAdapter(query, this.Connection);
        adapter.SelectCommand.Parameters.AddWithValue("@name", name);
        adapter.SelectCommand.Parameters.AddWithValue("@cls", cls);
    }

    XxxxxxDataSet dataset = new XxxxxxDataSet();
    adapter.Fill(dataset.Xxxxxx);
    return dataset.Xxxxxx;

     

     

    2009年1月20日 15:25
  •  

    私がやっているのは

    SELECT * FROM table WHERE (@name IS NULL OR name=@name) AND (@cls IS NULL OR cls=@cls)

    として条件が設定されない場合は@name, @clsにNULLが来るようにしています。

    2009年1月20日 15:40
  •  komi1 さんからの引用

    GridViewに複数のテーブルをリレーションでまとめて作ったDataSet1.xsdを使い
    データベースの情報をすべて表示させ、
    TextBox1、TextBox2に条件が入った場合はその条件にあったものに
    絞り込めるGridViewを表示できるようにしたいのですがQUERYの書き方がよくわかりません。
    現時点ではDataSet1.xsdに項目(名前)と(クラス)のフィルタに【?】を入れて作ったQUERYを使ってみましたが
    実行するとTextBox1、TextBox2の情報が両方とも一致している場合のみしかGridViewが表示されません。

    どのようにしたら最初はすべてのデータを表示し、条件を入れた場合のみその条件にあうものが表示されるようになるのでしょうか?

    条件を下記の様に編集するとか。
    # または、LIKE検索

     

    WHERE (@Param1 IS NULL

      OR 名前 = @Param1)

    AND (@Param2 IS NULL

      OR クラス = @Param2)

    2009年1月20日 16:17
  • 既に回答が出ていますが、ストアドプロシージャを使用して、そこでSQL文を組み立てるということも可能です。(単純に組み立てるとSQLインジェクションの原因になります!)

    この方法はもっと検索条件が複雑になった場合でも応用が効きますので、私が一番多く使うパターンです。TableAdapterはデータセットなどを簡単に扱えるようにラップしたものですから、それだけ応用が効きにくくなっています。そこで、応用を行うのをストアドプロシージャ側に持っていっているのです。

     

    また、ObjectDataSourceを使用されていますので、もし、TableAdapterに拘らないのであれば、そこでSQL文を組み立てることも可能です。(単純に組み立てるとSQLインジェクションの原因になります!)

    SqlDataSourceを使うのであれば、やはりSQL文を組み立てることが可能です。(単純に組み立てるとSQLインジェクションの原因になります!)

    2009年1月21日 1:37
    モデレータ
  •  Z9M9Z さんからの引用

    私がやっているのは

    SELECT * FROM table WHERE (@name IS NULL OR name=@name) AND (@cls IS NULL OR cls=@cls)

    として条件が設定されない場合は@name, @clsにNULLが来るようにしています。

     

    .NET の世界では String.Empty, null, DBNull.Value は違うものとして
    区別されます。

     

    SQL Server の世界でも、MSDN ライブラリよれば「NULL 値は 0、空白、
    長さ 0 の文字列 ("" など) のいずれとも異なります。」とのことです。

     

    SELECT ... WHERE @xxxxx IS NULL のパラメータ値を以下のように

    (xsd ファイルから自動生成されるコードがそのようになっています)、テキ

    ストボックスの初期値である String.Empty に設定した場合、

     

    Code Snippet

    sqlCommand.CommandText = "SELECT * FROM table WHERE (@xxxxx IS NULL)";
    sqlCommand.Parameters.Add(new SqlParameter("@xxxxx"));
    sqlCommand.Parameters[0].Value = String.Empty;

     

     

    WHERE 句の条件は '' IS NULL となり、FALSE と評価され、何も抽出され
    ないという結果になるはずです。

     

    ・・・と書いてレスを終わりにしようと思っていましたが、二人の方が違う意見

    を言われるので、念のため実際にコードを書いて検証してみました。

     

    結果はやはり '' IS NULL は FALSE と評価されたようで、何も抽出されな
    かったです。

     

    自分が知らないだけで、何かやり方があるのでょうか?

    2009年1月21日 14:03
  •  

    >結果はやはり '' IS NULL は FALSE と評価されたようで、何も抽出されな
    >かったです。

    うまく言えませんが、VWDのデザイナでTextBoxをSQLDataSourceのパラメータに設定すると、

    Code Snippet

     <SelectParameters>
                <asp:ControlParameter ControlID="TextBox1" Name="姓" PropertyName="Text" DefaultValue="" ConvertEmptyStringToNull="False" />

     

     

    のようにConvertEmptyStringToNullというパラメータが設定できます。これはDefaultではTrueであり、

    TextBox1が空文字列の場合にNullに変換してくれます。

    2009年1月21日 14:31
  • いつもお世話になります。

    試したのですが、すみません。使い方がわかりません。

     

    下記コードで

    ①名前

    ②クラス

    ③Me.Connection

    ④Dim dataset As New XxxxxxDataSet
    ⑤adapter.Fill(dataset.Xxxxxx)
    ⑥Return dataset.Xxxxxx

    が波線となるのですが

    名前=TextBox1.text

    クラス=TextBox2.textですよね?どうしたら、エラーがでなくなるのでしょうか?

    ③はConnectionはDataSet1TableAdapters.DataTable1TableAdapterのメンバではありません。というエラー内容です。

    ④~⑥はXXXXに何をいれたらいいのか、値を返すものをつくるコードなんでしょうが、

    よく理解できません。

     

    ご教授いただけないでしょうか?よろしくお願いいたします。

     

    Imports System
    Imports System.Data
    Imports System.Data.SqlClient

    Namespace DataSet1TableAdapters
        Partial Public Class DataTable1TableAdapter
            Dim query As String
            Dim adapter As SqlDataAdapter

            Public Sub KENSAKU()
                '名前がカラ、クラスがカラの時はqueryに全部で
                If TextBox1.text = [String].Empty AndAlso クラス = [String].Empty Then
                    query = "SELECT * FROM table"
                    adapter = New SqlDataAdapter(query, Me.Connection)
                    '名前がカラでクラスがカラでない場合はqueryにクラスで絞るで
                ElseIf 名前 = [String].Empty AndAlso クラス <> [String].Empty Then
                    query = "SELECT * FROM table WHERE クラス=@クラス"
                    adapter = New SqlDataAdapter(query, Me.Connection)
                    adapter.SelectCommand.Parameters.AddWithValue("@クラス", クラス)
                    '名前がカラでなくクラスがカラの場合はqueryに名前で絞るで
                ElseIf 名前 <> [String].Empty AndAlso クラス = [String].Empty Then
                    query = "SELECT * FROM table WHERE 名前=@名前"
                    adapter = New SqlDataAdapter(query, Me.Connection)
                    adapter.SelectCommand.Parameters.AddWithValue("@名前", 名前)
                    '名前もクラスもカラでない場合はqueryに名前、クラスで絞るで
                Else
                    query = "SELECT * FROM table WHERE 名前=@名前 AND クラス=@クラス"
                    adapter = New SqlDataAdapter(query, Me.Connection)
                    adapter.SelectCommand.Parameters.AddWithValue("@名前", 名前)
                    adapter.SelectCommand.Parameters.AddWithValue("@クラス", クラス)
                End If

     

                Dim dataset As New XxxxxxDataSet
                adapter.Fill(dataset.Xxxxxx)
                Return dataset.Xxxxxx
            End Sub
        End Class
    End Namespace

    2009年1月21日 14:58
  • > TextBox1が空文字列の場合にNullに変換してくれます。

     

    null は DBNull.Value  とは違うので、先の例で、

     

    Code Snippet

    sqlCommand.Parameters[0].Value = null;

     

     

    のようにするとエラーになるはずです。もちろん、データも
    抽出されません。

     

    ちなみに、

     

    Code Snippet
    sqlCommand.Parameters[0].Value = DBNull.Value;

     

     

    なら OK です。DB のテーブルのフィールドが NULL 許容であ
    る必要がありますが。

     

    でも、確かに SqlDataSource 経由でデータバインドされたテ
    キストボックスが空白のまま Insert, Update すると DB の
    該当フィールドは NULL になるので、null が DBNull.Value
    に変換されるのかもしれないですね。

     

    ObjectDataSource の場合も同じかもしれませんが、やっぱり、
    それに頼らず自力でコードを書くのが、個人的には良いと思い
    ます。

    2009年1月21日 15:07
  •  komi1 さんからの引用

    下記コードで

    ①名前

    ②クラス

    ③Me.Connection

    ④Dim dataset As New XxxxxxDataSet
    ⑤adapter.Fill(dataset.Xxxxxx)
    ⑥Return dataset.Xxxxxx

    が波線となるのですが

    名前=TextBox1.text

    クラス=TextBox2.textですよね?どうしたら、エラーがでなくなるのでしょうか?

    ③はConnectionはDataSet1TableAdapters.DataTable1TableAdapterのメンバではありません。というエラー内容です。

    ④~⑥はXXXXに何をいれたらいいのか、値を返すものをつくるコードなんでしょうが、

    よく理解できません。

     

    失礼な言い方かもしれませんが、あれからあまり勉強の方は進んでないよう

    で、依然として話が通じない状況のようです。

     

    掲示板のやり取りで、先にアップしたコードを完成をさせるのは無理っぽいの

    で、別の手を考えます(今日は遅いのでまた明日)。

     

    それとは別に、他の方から提案のあった、@xxxxx IS NULL を追加するのを

    試してみてください。

    2009年1月21日 15:30
  •  SurferOnWww さんからの引用

    > TextBox1が空文字列の場合にNullに変換してくれます。

     

    null は DBNull.Value  とは違うので、先の例で、

     

    Code Snippet

    sqlCommand.Parameters[0].Value = null;

     

     

    のようにするとエラーになるはずです。もちろん、データも
    抽出されません。

    # 私もZ9M9Zさんと同様のコメントをしたので追加でコメントしておきます

     

    MSDN

    TableAdapter での NULL 値の使用

    2009年1月21日 16:05
  •  SurferOnWww さんからの引用

    掲示板のやり取りで、先にアップしたコードを完成をさせるのは無理っぽいの

    で、別の手を考えます(今日は遅いのでまた明日)。

     

    最初の私の案はちょっと難しそうで、@xxxx IS NULL 案も元々 NULL 不可だと
    すると NULL 許容に変えて思わぬところで問題が出る可能性を排除できないと
    いうことで、@xxxx IS NULL 案を参考にそれを少し変更して以下のようにする
    のが簡単でよさそうです。

     

    (1) TextBox.Text の初期値は "ALL" にしておく。(注)

     

    (2) SELECT クエリの WHERE 句は以下のようにする。

     

      WHERE (@name = 'ALL' OR 名前 = @name) AND (@cls = 'ALL' OR クラス = @cls)

     

    そんなクエリでいいのかという気もしますが、一応それで動くことは検証済み
    です。


    (注)TextBox に替えて DropDownList を2つ使い、それぞれに名前とクラス
       をデータバインドして、それから選ぶようにするのが、SQL インジェク
       ション防止やユーザビリティ向上によさそうです。

    2009年1月22日 15:28
  •  karashima さんからの引用

    MSDN

    TableAdapter での NULL 値の使用

     

    DB のフィールドが NULL 不可に設定されている場合、自動生成される GetDataByXxxx メ

    ソッドのコードでは null を受け付けないのですが、それをすると、例えば引数が int だったの

    が int? になって、さらに null を受けたときは DBNull.Value に変えるコードに変更されますね。

    2009年1月22日 15:46
  • ご回答いただきありがとうございます。

    SQLserverを使ってやってみましたら、うまく思うとおりの動作ができました。

    WHERE          (@Param1 = 'ALL') AND (@Param2 = 'ALL') OR
                         (@Param1 = 'ALL') AND (情報.クラス = @Param2) OR
                         (@Param2 = 'ALL') AND (情報.名前 = @Param1) OR
                         (情報.クラス = @Param2) AND (情報.名前 = @Param1)

     

    ですが、Accessを使うとどのようにしたらいいのでしょうか?

    WHERE          (? = 'ALL') AND (? = 'ALL') OR
                         (? = 'ALL') AND (情報.クラス = ?) OR
                         (? = 'ALL') AND (情報.名前 = ?) OR
                         (情報.クラス = ?) AND (情報.名前 = ?)

     

    SQLでは「?」を入れると項目ごとに@Param1 、@Param2となるのですが

    Accessではどの項目でも?と表示されてしまい、

    思うような操作ができません。

     

    2009年1月23日 15:00
  • Access なんですか?

     

    それならそうと一番最初に書いておいてください。回答者3人とも

    SQL Server だと思って回答してしまったようで、時間と労力の無

    駄になってしまったようです。

     

    まぁ、全くの無駄というわけではなく、Access でもウィザードの

    「パラメータの定義」のところで、SQL Server なら2つで済むパ

    ラメータの設定が8つに増えるだけですが。

     

    設定するのは、TextBox1 か TextBox2 のいずれかで、? の順

    番にロジックを考えてどちらか適切に選べばいいはずです。

    2009年1月23日 17:44
  • いまさらかもしれませんが...

     

    textBoxに文字が設定されてない場合にNullではなく空文字列が入るのであれば

    IS NULLの代わりに(@param = '' OR 列 = @param)でよくて特に'ALL'と指定しなくても

    いいのではないでしょうか。

    2009年1月24日 2:19
  •  Z9M9Z さんからの引用

    textBoxに文字が設定されてない場合にNullではなく空文字列が入るのであれば

    IS NULLの代わりに(@param = '' OR 列 = @param)でよくて特に'ALL'と指定しなくても

    いいのではないでしょうか。

     

    ALL を使うことを提案した理由は、自分が書いたコードでコントロール可能だ
    からです。

     

    「コントロール可能」というのは、ALL とすれば、そのまま ALL が渡されるの
    で、結果が自分の思ったとおりになるという意味です。

     

    TextBox から SQL Server に投げられるクエリ文字の間には、ControlParameter,
    ObjectDataSource, TableAdapter, ADO.NET ライブラリがあります。空白の場合、
    それがそこでどのように変換されていくか見えないところがあって、自分的にはあ
    まり気分が良くないんです。

     

    @xxxx IS NULL とか @xxxx = '' の場合、TextBox の空白がどのように変換され
    て、最終的に期待する文字(この場合 NULL とか '')に変換されるか、ライブラ
    リ任せというのが気に入らないです。まあ、それは自分がプロパティの設定など
    に無知だからで、熟知している方には当てはまらないかもしれませんが。

     

    もう一つの理由は、空白より ALL(日本語で「全部」などとしてもいいです)と表示さ

    れていた方がユーザビリティの面でよさそうだと思ったこともあります。

    2009年1月24日 7:12
  •  

    なるほど、そういう理由でしたか。

    了解しました。

    2009年1月24日 10:26
  • WHERE          (? = 'ALL') AND (? = 'ALL') OR
                         (? = 'ALL') AND (クラス = ?) OR
                         (? = 'ALL') AND (名前 = ?) OR
                         (クラス = ?) AND (名前 = ?)

     

    TextBox1、TextBox2、TextBox1、TextBox2、TextBox2、TextBox1、TextBox2、TextBox1で

    思うような動作ができるようになりました。

     

    SQLとACCESSでは違うんですね。

    今回教えていただいたのを元にいろいろな条件指定をしていきたいと思います。

     

    教えていただき本当にありがとうございました。

    2009年1月24日 13:01
  • 前のレスに書いた、TextBox に替えて DropDownList を使う案も検討してみてく

    ださい。実際に試してみると、たぶん、そのほうが良いと思うでしょう。

     

    TextBox1, TextBox2 を以下のように置き換えれば実現できると思います。デー

    タベースのフォルダ名/名前(下記では App_Data/Access.mdb)、フィールド名

    (下記では「名前」「クラス」 )、テーブル名(下記では table)は実際にあわせて

    書き直してください。

     

    Code Snippet

    <asp:AccessDataSource ID="AccessDataSource1"
        runat="server"
        DataFile="~/App_Data/Access.mdb"
        SelectCommand="SELECT DISTINCT [名前] FROM [table]">
    </asp:AccessDataSource>
    <asp:DropDownList ID="DropDownList1"
        runat="server"
        DataSourceID="AccessDataSource1"
        AppendDataBoundItems="True"
        DataTextField="名前"
        DataValueField="名前">
        <asp:ListItem Value="ALL">ALL</asp:ListItem>
    </asp:DropDownList>

    <asp:AccessDataSource ID="AccessDataSource2"
        runat="server"
        DataFile="~/App_Data/Access.mdb"
        SelectCommand="SELECT DISTINCT [クラス] FROM [table]">
    </asp:AccessDataSource>
    <asp:DropDownList ID="DropDownList2"
        runat="server"
        DataSourceID="AccessDataSource2"
        AppendDataBoundItems="True"
        DataTextField="クラス"
        DataValueField="クラス">
        <asp:ListItem Value="ALL">ALL</asp:ListItem>
    </asp:DropDownList>

     

     

    2009年1月25日 3:39
  • ドロップダウンリストにして出来ました。

    ありがとうございます。これで、文字間違えなどの問題が防げます。

     

    ですが、Accessのほうはうまくできたのですが

    SQL版の方がうまくできません。

     

    クエリビルダ上では

    WHERE          (@Param1 = 'ALL') AND (@Param2 = 'ALL') OR
                         (@Param1 = 'ALL') AND (情報.クラス = @Param2) OR
                         (@Param2 = 'ALL') AND (情報.名前 = @Param1) OR
                         (情報.クラス = @Param2) AND (情報.名前 = @Param1)

    でクエリの実行で

    @Param1=ALL・@Param2=ALL  全て表示

    @Param1=相沢・@Param2=ALL 相沢さんの情報のみ表示

    @Param1=ALL・@Param2=A      クラスAのみ表示

    @Param1=相沢・@Param2=A      相沢さんの情報のみ表示

     

    と、うまく思ったとおりの表示がされるのですが

    これを実際にaspxでGridViewに表示させると

    @Param1=ALL・@Param2=ALL  何も表示されない

    @Param1=相沢・@Param2=ALL  何も表示されない

    @Param1=ALL・@Param2=A       クラスAのみ表示

    @Param1=相沢・@Param2=A      相沢さんの情報のみ表示

    というような@Param1がうまくできていない表示となってしまいます。

     

    クリエビルダ上ではうまく動くのになぜできなくなってしますのでしょうか?

     

    <%@ Page Language="VB" %>

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <script runat="server">

    </script>

    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title>無題のページ</title>
    </head>
    <body>
        <form id="form1" runat="server">
        <p>
            名前<aspBig SmileropDownList ID="DropDownList1" runat="server"
                AppendDataBoundItems="True" DataSourceID="ObjectDataSource1" DataTextField="名前"
                DataValueField="名前">
                <asp:ListItem>ALL</asp:ListItem>
            </aspBig SmileropDownList>
            <aspSurprisebjectDataSource ID="ObjectDataSource1" runat="server"
                OldValuesParameterFormatString="original_{0}" SelectMethod="GetData"
                TypeName="DataSet1TableAdapters.DataTable1TableAdapter">
            </aspSurprisebjectDataSource>
             クラス<aspBig SmileropDownList ID="DropDownList2" runat="server"
                AppendDataBoundItems="True" DataSourceID="ObjectDataSource2"
                DataTextField="クラス" DataValueField="クラス">
                <asp:ListItem>ALL</asp:ListItem>
            </aspBig SmileropDownList>
            <asp:Button ID="Button1" runat="server" Text="Button" />
            <aspSurprisebjectDataSource ID="ObjectDataSource2" runat="server"
                OldValuesParameterFormatString="original_{0}" SelectMethod="GetData"
                TypeName="DataSet1TableAdapters.DataTable1TableAdapter">
            </aspSurprisebjectDataSource>
            <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
                DataKeyNames="ID" DataSourceID="ObjectDataSource3">
                <Columns>
                    <asp:BoundField DataField="ID" HeaderText="ID" ReadOnly="True"
                        SortExpression="ID" />
                    <asp:BoundField DataField="名前" HeaderText="名前" SortExpression="名前" />
                    <asp:BoundField DataField="性別" HeaderText="性別" SortExpression="性別" />
                    <asp:BoundField DataField="クラス" HeaderText="クラス" SortExpression="クラス" />
                    <asp:BoundField DataField="国語" HeaderText="国語" SortExpression="国語" />
                    <asp:BoundField DataField="算数" HeaderText="算数" SortExpression="算数" />
                    <asp:BoundField DataField="社会" HeaderText="社会" SortExpression="社会" />
                </Columns>
            </asp:GridView>
            <aspSurprisebjectDataSource ID="ObjectDataSource3" runat="server"
                OldValuesParameterFormatString="original_{0}" SelectMethod="GetDataBy"
                TypeName="DataSet1TableAdapters.DataTable1TableAdapter">
                <SelectParameters>
                    <asp:ControlParameter ControlID="DropDownList1" Name="Param1"
                        PropertyName="SelectedValue" Type="String" />
                    <asp:ControlParameter ControlID="DropDownList2" Name="Param2"
                        PropertyName="SelectedValue" Type="String" />
                </SelectParameters>
            </aspSurprisebjectDataSource>
        </p>
        <div>
       
        </div>
        </form>
    </body>
    </html>

    2009年1月25日 6:00
  • ざっと見た限り、DropDownList の ListItem の Value の設定がないのが

    問題です。以下のようにします。

     

    Code Snippet

    <asp:ListItem Value="ALL">ALL</asp:ListItem>

     

     

    他にも問題あるかもしれませんが、とりあえずそこを修正して試してみて

    ください。

     

    #コードは Code Snippet に入れてください。文字化けすると、読む気力

     がなくなってきます。

     

    #DropDownList には SqlDataSource を使ったほうが簡単だと思いま

     す。

     

     

     

    2009年1月25日 7:11
  • そこに問題があるのかどうか分かりませんが、ObjectDataSource でなく
    SqlDataSource を使った例をアップしておきます。

     

    接続文字列(下記では ConnectionStrings:Northwind)、フィールド名
    (下記では「名前」「クラス」 )、テーブル名(下記では table)は実
    際にあわせて書き直してください。

     

    Code Snippet

    <asp:SqlDataSource ID="SqlDataSource1"
        runat="server"
        ConnectionString="<%$ ConnectionStrings:Northwind %>"
        SelectCommand="SELECT DISTINCT [名前] FROM [table]">
    </asp:SqlDataSource>
    <asp:DropDownList ID="DropDownList1"
        runat="server"
        AppendDataBoundItems="True"
        DataSourceID="SqlDataSource1"
        DataTextField="名前"
        DataValueField="名前">
        <asp:ListItem Value="ALL">ALL</asp:ListItem>
    </asp:DropDownList>

    <asp:SqlDataSource ID="SqlDataSource2"
        runat="server"
        ConnectionString="<%$ ConnectionStrings:Northwind %>"
        SelectCommand="SELECT DISTINCT [クラス] FROM [table]">
    </asp:SqlDataSource>
    <asp:DropDownList ID="DropDownList2"
        runat="server"
        AppendDataBoundItems="True"
        DataSourceID="SqlDataSource2"
        DataTextField="クラス"
        DataValueField="クラス">
        <asp:ListItem Value="ALL">ALL</asp:ListItem>
    </asp:DropDownList>

     

     


    2009年1月25日 9:32
  • ありがとうございます。

     

    SqlDataSourceを使ったものはうまく表示できるようになりました。

    ですがObjectDataSourceでは

    Code Snippet

      <asp:ListItem Value="ALL">ALL</asp:ListItem>

     

     

    にしても問題が変わらないままです。

    2009年1月25日 12:12
  • それはたぶん ObjectdataSource で指定しているメソッド SelectMethod="GetData"
    が適切ではないからでしょう。勉強を進めて、どうすればよいか考えてみてくださ
    い。

    2009年1月25日 13:05
  • クエリを
    WHERE          (? = 'ALL') AND (? = 'ALL') OR
                         (? = 'ALL') AND (クラス = ?) OR
                         (? = 'ALL') AND (名前 = ?) OR
                         (クラス = ?) AND (名前 = ?)
    と指定し、ObjectDataSourceを
    DropDownList1、DropDownList2、DropDownList1、DropDownList2、DropDownList2、
    DropDownList1、DropDownList2、DropDownList1で
    指定し、思うような操作ができるようになったのですが

    このままでは全てのデータからのDropDownListの指定条件が抽出されますが
    これを国語が100点、80点、60点のもののみのデータ表示という条件を
    付け加えるには如何したらいいのでしょうか?

    (kokugo = 100) OR (kokugo = 80) OR (kokugo = 600) AND を付け加えてみたりとしてみたのですが
    ALLの場合のみよく、DropDownListを指定するとうまく動作しなくなります。

    どのようにしたら指定ができるのでしょうか?

    • 回答としてマーク komi1 2009年1月31日 15:55
    • 回答としてマークされていない komi1 2009年1月31日 15:55
    2009年1月31日 15:55
  •  DropDownList の方が AccessDataSource なのか、依然として ObjectDataSource
    なのかが不明です。
    2009年1月31日 18:15
  •  

    最終的にどのようなコントロールを使ったのか分かりませんが・・・

    DropDownList のデータソースは AccessDataSource のまま変更しておらず、GridView
    のデータソース ObjectDataSource の SelectMethod に指定したGetDataBy メソッドの
    WHERE 句を書き換えているのでしょうか?

    であれば、たぶん、論理演算子(NOT、AND、OR)の優先順位が考えられていないことが
    うまくいかない原因でしょう。

    優先順位は、高い方から NOT、AND、OR です。カッコを使用することによって、検索条
    件におけるこれらの優先順位を変更することができます。以下のようにしてみたらどう
    なるか、試してみてください。(未検証です。DB がないので)

    WHERE
    ( (kokugo = 100) OR (kokugo = 80) OR (kokugo = 60) )
    AND
    ( (? = 'ALL') AND (? = 'ALL') OR
    (? = 'ALL') AND (クラス = ?) OR
    (? = 'ALL') AND (名前 = ?) OR
    (クラス = ?) AND (名前 = ?) )

    2009年2月1日 5:59
  • いつも、データセットでGetDataBy メソッドの WHERE 句をフィルタを使用して書き換えて
    ObjectDataSourceで使用しているのですが、
    AccessDataSourceやSQLDataSourceを使ったほうがいいのでしょうか???

    そして、ありがとうございました。
    括弧をつけることで動作がうまくいくようになりました。
    2009年2月1日 6:49
  •  

    > いつも、データセットでGetDataBy メソッドの WHERE 句をフィルタを使用して書き換えて
    > ObjectDataSourceで使用しているのですが、
    > AccessDataSourceやSQLDataSourceを使ったほうがいいのでしょうか???

    どちらを使ったほうが簡単にできるかということで判断すると、AccessDataSource や
    SqlDataSource の方なのでそれを使いました。余計(?)な手間をかけて面倒なこと
    をするより、簡単にできたほうがいいですよね? 間違いも少なくなりますし。

    自分的には、ウィザードベースでは作れないようなクエリが必要な場合など、
    SqlDataSource では無理なときのみ ObjectDataSource を使うのがよいと思っていま
    す。

    2009年2月1日 9:50
  • SQL文が以前より上達し、以前はコードは断念しデータセットによるノンコーディングの方法で解決したのですが
    書けるようになりましたのでUPさせていただきます。

    アドバイスいただいた方にはとても感謝しております。読み返すと、本当に自分がわかっていなかったのがよくわかりました。
    親切にお付き合いいただきありがとうございます。コードがかけるようになりました。

    <%@ Page Language="VB" %>
    
    <%@ Import Namespace="System.Data" %>
    
    <%@ Import Namespace="System.Data.SqlClient" %>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <script runat="server">
    
        Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs)
            Dim conStr As String = ConfigurationManager.ConnectionStrings("project_jobConnectionString").ConnectionString
    
            Dim strSQL As String
            
            '名前がカラ、性別がカラの時は全部で
            If DropDownList1.Text = [String].Empty AndAlso DropDownList2.Text = [String].Empty Then
                strSQL = "SELECT 名前.ID, 名前.名前, 名前.性別, 成績.国語, 成績.数学, 成績.社会 FROM 名前 INNER JOIN 成績 ON 名前.ID = 成績.ID"
                '名前がカラで性別がカラでない場合
            ElseIf DropDownList1.Text = [String].Empty AndAlso DropDownList2.Text <> [String].Empty Then
                strSQL = "SELECT 名前.ID, 名前.名前, 名前.性別, 成績.国語, 成績.数学, 成績.社会 FROM 名前 INNER JOIN 成績 ON 名前.ID = 成績.ID WHERE (@Param1 = '') OR (名前.性別 = @Param1)"
                '名前がカラでなく性別がカラの場合
            ElseIf DropDownList1.Text <> [String].Empty AndAlso DropDownList2.Text = [String].Empty Then
                strSQL = "SELECT 名前.ID, 名前.名前, 名前.性別, 成績.国語, 成績.数学, 成績.社会 FROM 名前 INNER JOIN 成績 ON 名前.ID = 成績.ID WHERE (@Param1 = '') OR (名前.名前 = @Param1)"
                '名前も性別もカラでない場合
            Else
                strSQL = "SELECT 名前.ID, 名前.名前, 名前.性別, 成績.国語, 成績.数学, 成績.社会 FROM 名前 INNER JOIN 成績 ON 名前.ID = 成績.ID WHERE (@Param1 = '') OR (名前.名前 = @Param1) AND (@Param2 = '') OR (名前.性別 = @Param2)"
            End If
    
            Using con As New SqlConnection(conStr)
                Using cmd As New SqlCommand(strSQL, con)
                    Dim dr As SqlDataReader
                    '名前がカラ、性別がカラの時は全部で
                    If DropDownList1.Text = [String].Empty AndAlso DropDownList2.Text <> [String].Empty Then
                        cmd.Parameters.AddWithValue("@Param1", DropDownList2.Text)
                        '名前がカラでなく性別がカラの場合
                    ElseIf DropDownList1.Text <> [String].Empty AndAlso DropDownList2.Text = [String].Empty Then
                        cmd.Parameters.AddWithValue("@Param1", DropDownList1.Text)
                        '名前も性別もカラでない場合
                    Else
                        cmd.Parameters.AddWithValue("@Param1", DropDownList1.Text)
                        cmd.Parameters.AddWithValue("@Param2", DropDownList2.Text)
                    End If
                    con.Open()
                    dr = cmd.ExecuteReader(Data.CommandBehavior.CloseConnection)
                    GridView1.DataSource = dr
                    GridView1.DataBind()
                    dr.Close()
                End Using
            End Using
        End Sub
    </script>
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title>無題のページ</title>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
        
            名前<asp:DropDownList ID="DropDownList1" runat="server" 
                DataSourceID="SqlDataSource1" DataTextField="名前" DataValueField="名前" 
                AppendDataBoundItems="True">
                <asp:ListItem Value="">ALL</asp:ListItem>
            </asp:DropDownList>
             性別<asp:DropDownList ID="DropDownList2" runat="server" 
                DataSourceID="SqlDataSource1" DataTextField="性別" DataValueField="性別"
                AppendDataBoundItems="True">
                <asp:ListItem Value="">ALL</asp:ListItem>
            </asp:DropDownList>
            <asp:SqlDataSource ID="SqlDataSource1" runat="server" 
                ConnectionString="<%$ ConnectionStrings:project_jobConnectionString2 %>" 
                SelectCommand="SELECT DISTINCT * FROM [名前]"></asp:SqlDataSource>
            <asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="Button" />
        
        </div>
            <asp:GridView ID="GridView1" runat="server">
            </asp:GridView>
        
        </form>
    </body>
    </html>
    
    2009年5月30日 16:00