トップページへ PASSJ ブログへ
トップページへ
分科会
特集!
コミュニケーション
資格
セミナー・コンファレンス
インフォメーション



Webテクノロジー ボードリーダー:小川 貢

毎月第2、第4木曜日はボードリーダーからのレポートを掲載いたします。
 
   

2004年2月12日
『どっとねっとと雑多な日々 21』

今回は「 ADO.NET でレコード件数を取得する方法」について、書きたいと思います。

ADO であれば、ADODB.Recordset の RecordCount にて件数は取得できます。
※ CursorType や LockType などが適切に設定されている必要がありますが。

では、ADO.NET の SqlDataReader ではどうするのでしょうか?
答えは、「自分でカウントする」です。

using System.Data;
using System.Data.SqlClient;

private void ExecuteSqlDataReader1_Click(object sender, System.EventArgs e)
{
  int count = 0;
  using(SqlConnection sqlConnection = new SqlConnection("Data Source=(local);Initial Catalog=pubs;Trusted_Connection=yes;"))
  using(SqlCommand sqlCommand = new SqlCommand("SELECT * FROM titles", sqlConnection))
  {
    try
    {
     sqlConnection.Open();
     SqlDataReader sqlDataReader =       sqlCommand.ExecuteReader(CommandBehavior.CloseConnection);
     while(sqlDataReader.Read())
     {
        // 処理
        count++;
      }
      sqlDataReader.Close();
    }
    catch(SqlException sex)
    {
      System.Diagnostics.Debug.WriteLine(sex.Message);
    }
  }
  this.recordCount.Text = count.ToString();
}

これだと SqlDataReader を取得した直後に件数がわかりません。
ではどうするか?
賢明な方であれば、いくつかの方法を思い浮かぶと思います。

1.レコード件数をカウントする SQL とテーブルのデータを取得する SQL を
 同時に実行する
2.ストアドプロシージャなどの OUTPUT や RETURN で件数を取得する
3.あきらめて DataSet を使う

という感じでしょうか。

この 3 つのやり方で、明らかに 1 つだけ要件を満たさないものがあります。
それは OUTPUT や RETURN で件数を取得する場合です。

それはなぜかというと SqlDataReader が開いている間、OUTPUT パラメータ
や RETURN の値を取得することはできないからです。

SqlDataReader を使うことが要件であれば、3 つめも要件を満たさないと考
えることはできますが、データを取得した直後にレコード件数が取得できれ
ば良いという要件であれば、条件を満たせると思います。

以下、複数の SQL を実行して、レコード件数を取得する方法と DataSet で
レコード件数を取得する方法の例を記載します。

// 複数 SQL 実行
private void ExecuteSqlDataReader2_Click(object sender, System.EventArgs e)
{
  using(SqlConnection sqlConnection = new SqlConnection("Data Source=(local);Initial Catalog=pubs;Trusted_Connection=yes;"))
  using(SqlCommand sqlCommand = new SqlCommand("SELECT COUNT(*) As RecCount FROM titles;SELECT * FROM titles", sqlConnection))
  {
    try
    {
      sqlConnection.Open();
      SqlDataReader sqlDataReader = sqlCommand.ExecuteReader(CommandBehavior.CloseConnection);

      if(sqlDataReader.Read())
      {
      this.recordCount.Text = sqlDataReader[0].ToString();
      }
      if(sqlDataReader.NextResult())
      {
        // 処理
      }
      sqlDataReader.Close();
    }
    catch(SqlException sex)
    {
      System.Diagnostics.Debug.WriteLine(sex.Message);
    }
  }
}

// DataSet 使用
private void ExecuteDataSet_Click(object sender, System.EventArgs e)
{
  using(SqlConnection sqlConnection = new SqlConnection("Data Source=(local);Initial Catalog=pubs;Trusted_Connection=yes;"))
  using(SqlCommand sqlCommand = new SqlCommand("SELECT * FROM titles", sqlConnection))
  using(SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(sqlCommand))
  using(DataSet dataSet = new DataSet("titles"))
  {
    try
    {
      sqlConnection.Open();
      sqlDataAdapter.Fill(dataSet, "titles");
      DataTable dataTable = dataSet.Tables["titles"];
      this.recordCount.Text = dataTable.Rows.Count.ToString();
      // 処理
      dataTable.Dispose();
    }
    catch(SqlException sex)
    {
      System.Diagnostics.Debug.WriteLine(sex.Message);
    }
  }
}

 

ボードリーダーレポート トップページへ

 

 
PASSJメールニュース 著作権ついて プライバシーポリシー リンクポリシー お問い合わせ
(C) 2005 Professional Association for SQL Server Japan. All rights reserved.