|   | 
| 
 .NET TIPS 
[ADO.NET]複数のselect文をまとめて実行するには?
デジタルアドバンテージ 
2004/03/19 | 
  | 
 
 | 
   ADO.NETを使用してデータセットにデータベースの検索結果を読み込む場合、通常は次のように1つのselect文に付き1つのデータアダプタを作成する(ADO.NETの基本的なプログラミングについては「連載:ADO.NET基礎講座」を参考にしていただきたい)。
string connStr = "接続文字列……";
string selectStr = "SELECT pub_id, pub_name FROM publishers";
SqlDataAdapter da = new SqlDataAdapter(selectStr, connStr);
DataSet ds = new DataSet();
da.Fill(ds, "publishers");
 複数のselect文を利用する場合には、同じようにして、その数だけデータアダプタを作成してもよいが、select文をセミコロン(;)で連結したバッチSQLステートメント(バッチ・クエリとも呼ばれる)を使用すれば、1度の問い合わせで複数のselect文を実行することができる。
string connStr = "接続文字列……";
string selectStr = "SELECT pub_id, pub_name FROM publishers;"
                 + "SELECT emp_id, fname, pub_id FROM employee";
SqlDataAdapter da = new SqlDataAdapter(selectStr, connStr);
DataSet ds = new DataSet();
da.Fill(ds);
 このように記述してデータセットのFillメソッドを呼び出すと、データセット内に「Table」と「Table1」という既定の名前が付けられた2つのデータテーブルが作成される(さらに検索結果が存在する場合には、「Table2」「Table3」……と続く)。データアダプタは複数の検索結果を自動的に処理できるというわけである。
 なお、第2パラメータを省略せずにFillメソッドを実行した場合に検索結果が複数あると、作成されるデータテーブルの名前は「publishers」「publishers1」「publishers2」のように、「指定した名前+連番」となる。
テーブル・マップによるデータテーブル名の指定
 作成されるデータテーブルに独自の名前を付けたい場合には、Fillメソッドを実行する前に、データアダプタに対して次のようにしてテーブル・マップを追加しておけばよい。
da.TableMappings.Add("Table", "publishers");
da.TableMappings.Add("Table1", "employee");
 このように設定しておいてFillメソッドを実行すると、作成されるデータテーブルの名前は、それぞれ「publishers」と「employee」となる。
複数のselect文をまとめて実行するサンプル・プログラム
 以下のASP.NETのサンプル・プログラムは、SQL Server 2000やMSDEに付属しているサンプル・データベース「pubs」のpublishersテーブルから、2つのテーブル「publishers」、「employee」のレコードを1つのSQL文で取得している例である。
 この2つのテーブル間にはリレーションが設定されており、pub_id列が外部キーとなっている。サンプル・プログラムでは、データセットに読み込んだテーブルに「publishers」「employee」という名前を付け、さらに次のようにしてデータセット内で2つのデータテーブル間に「pub_emp」という名前のリレーションを設定している。
ds.Relations.Add(
    new DataRelation("pub_emp",
        ds.Tables["publishers"].Columns["pub_id"],
        ds.Tables["employee"].Columns["pub_id"]));
 そして、リレーションが設定されているこの2つのデータテーブルの内容を、入れ子になったDataGridコントロール(後述)により表示している。
<%@ Page Language="C#" EnableViewState="false" %> 
<%@ Import Namespace="System.Data" %> 
<%@ Import Namespace="System.Data.SqlClient" %> 
 
<html> 
<head> 
  <script runat="server"> 
    void Page_Load(object sender, EventArgs e) { 
 
      string connStr = "Server=(local)\\NetSDK;" 
                     + "Trusted_Connection=yes;" 
                     + "database=pubs"; 
      string selectStr 
          = "SELECT pub_id, pub_name FROM publishers;" 
          + "SELECT emp_id, fname, pub_id FROM employee"; 
 
      SqlDataAdapter da 
          = new SqlDataAdapter(selectStr, connStr); 
      da.TableMappings.Add("Table", "publishers"); 
      da.TableMappings.Add("Table1", "employee"); 
 
      DataSet ds = new DataSet(); 
      da.Fill(ds); 
 
      ds.Relations.Add( 
          new DataRelation("pub_emp", 
              ds.Tables["publishers"].Columns["pub_id"], 
              ds.Tables["employee"].Columns["pub_id"])); 
 
      MyGrid.DataSource = ds.Tables["publishers"]; 
      MyGrid.DataBind(); 
    } 
 
    DataView GetChild(object item, string relName) { 
      DataRowView drv = (DataRowView)item; 
      return drv.CreateChildView(relName); 
    } 
  </script> 
</head> 
 
<body> 
  <asp:DataGrid id="MyGrid" 
      AutoGenerateColumns="false" 
      CellPadding="4" 
      runat="server" > 
 
    <HeaderStyle BackColor="#BB2255" ForeColor="white" /> 
    <ItemStyle   BackColor="#FFEEEE" /> 
    <AlternatingItemStyle BackColor="#FFDDDD" /> 
 
    <Columns> 
      <asp:BoundColumn 
          DataField="pub_id" HeaderText="出版社ID" /> 
      <asp:BoundColumn 
          DataField="pub_name" HeaderText="出版社名" /> 
 
      <asp:TemplateColumn HeaderText="社員ID/社員名"> 
        <ItemTemplate> 
          <asp:DataGrid id="MySubGrid" 
              AutoGenerateColumns="false" 
              CellPadding="4" 
              DataSource='<%# GetChild(Container.DataItem, "pub_emp") %>' 
              ShowHeader="false" 
              runat="server" > 
 
            <HeaderStyle BackColor="#5522BB" ForeColor="white" /> 
            <ItemStyle   BackColor="#EEEEFF" /> 
            <AlternatingItemStyle BackColor="#DDDDFF" /> 
 
            <Columns> 
              <asp:BoundColumn DataField="emp_id" /> 
              <asp:BoundColumn DataField="fname" /> 
            </Columns> 
          </asp:DataGrid> 
        </ItemTemplate> 
      </asp:TemplateColumn> 
    </Columns> 
  </asp:DataGrid> 
</body> 
</html> 
 | 
 
 
 | 
 
| 複数のselect文をまとめて実行するC#のサンプル・プログラム(multisel.cs.aspx) | 
| 
 | 
 
<%@ Page Language="VB" EnableViewState="false" %> 
<%@ Import Namespace="System.Data" %> 
<%@ Import Namespace="System.Data.SqlClient" %> 
 
<html> 
<head> 
  <script runat="server"> 
    Private Sub Page_Load(ByVal sender As System.Object, _ 
                          ByVal e As System.EventArgs) 
 
      Dim connStr As String = "Server=(local)\NetSDK;" _ 
                            & "Trusted_Connection=yes;" _ 
                            & "database=pubs" 
      Dim selectStr As String = _ 
            "SELECT pub_id, pub_name FROM publishers;" _ 
          & "SELECT emp_id, fname, pub_id FROM employee" 
 
      Dim da As SqlDataAdapter _ 
          = New SqlDataAdapter(selectStr, connStr) 
      da.TableMappings.Add("Table", "publishers") 
      da.TableMappings.Add("Table1", "employee") 
 
      Dim ds As DataSet = New DataSet 
      da.Fill(ds) 
 
      ds.Relations.Add( _ 
          New DataRelation("pub_emp", _ 
              ds.Tables("publishers").Columns("pub_id"), _ 
              ds.Tables("employee").Columns("pub_id"))) 
 
      MyGrid.DataSource = ds.Tables("publishers") 
      MyGrid.DataBind() 
    End Sub 
 
    Function GetChild(ByVal item As Object, _ 
                      ByVal relName As String) As DataView 
      Dim drv As DataRowView = CType(item, DataRowView) 
      Return drv.CreateChildView(relName) 
    End Function 
  </script> 
</head> 
 
<body> 
  <asp:DataGrid id="MyGrid" 
      AutoGenerateColumns="false" 
      CellPadding="4" 
      runat="server" > 
 
    <HeaderStyle BackColor="#BB2255" ForeColor="white" /> 
    <ItemStyle   BackColor="#FFEEEE" /> 
    <AlternatingItemStyle BackColor="#FFDDDD" /> 
 
    <Columns> 
      <asp:BoundColumn 
        DataField="pub_id" HeaderText="出版社ID" /> 
      <asp:BoundColumn 
        DataField="pub_name" HeaderText="出版社名" /> 
 
      <asp:TemplateColumn HeaderText="社員ID/社員名"> 
        <ItemTemplate> 
          <asp:DataGrid id="MySubGrid" 
              AutoGenerateColumns="false" 
              CellPadding="4" 
              DataSource='<%# GetChild(Container.DataItem, " pub_emp") %>' 
              ShowHeader="false" 
              runat="server" > 
 
            <HeaderStyle BackColor="#5522BB" ForeColor="white" /> 
            <ItemStyle   BackColor="#EEEEFF" /> 
            <AlternatingItemStyle BackColor="#DDDDFF" /> 
 
            <Columns> 
              <asp:BoundColumn DataField="emp_id" /> 
              <asp:BoundColumn DataField="fname" /> 
            </Columns> 
          </asp:DataGrid> 
        </ItemTemplate> 
      </asp:TemplateColumn> 
    </Columns> 
  </asp:DataGrid> 
</body> 
</html> 
 | 
 
 
 | 
 
| 複数のselect文をまとめて実行するVB.NETのサンプル・プログラム(multisel.vb.aspx) | 
| 
 | 
 なお、プログラムで使用しているデータベースへの接続文字列(変数connStr)の内容は環境に応じて適宜変更する必要がある。 
 このサンプル・プログラムの実行結果は次の画面のようになる。
 
  | 
 
| 複数のselect文をまとめて実行するプログラムの実行例 | 
 画面の例のような「入れ子になったDataGridコントロール」を表示する方法については、「[ASP.NET]DataGridコントロールを階層表示させるには?」で詳しく解説している。
カテゴリ:データベース 処理対象:データセット 
使用ライブラリ:DataSetクラス(System.Data名前空間) 
使用ライブラリ:DataTableクラス(System.Data名前空間) 
使用ライブラリ:DataRelationクラス(System.Data名前空間) 
関連TIPS:[ASP.NET]DataGridコントロールを階層表示させるには?
 | 
 
 
|  
 | 
 
generated by  
 | 
 
 
 |