web-dev-qa-db-ja.com

DataReaderの倍数テーブル

私は通常、DataSetを使用します。これは非常に柔軟だからです。最近、コード最適化タスクを割り当てられました。データベースへのヒットを減らすために、プロシージャ内の2つのクエリを変更しています。 1つのクエリはcountを返し、もう1つのクエリはactual dataを返します。つまり、My stored procedureは2つのテーブルを返します。これで、DataSetsを使用して両方のテーブルを読み取る方法がわかりましたが、DataReaderを使用して両方のテーブルを読み取る必要があります。それを探して、私は This を見つけました。

記事に従い、次のようにコードを記述しました。

dr = cmd.ExecuteReader();
while (dr.Read())
{


}
if (dr.NextResult()) // this line throws exception
{
   while (dr.Read())
{

しかし、dt.NextResultで例外が発生しています。例外は次のとおりです。

Invalid attempt to call NextResult when reader is closed.

上記のエラーもグーグルで検索しましたが、それでも問題を解決できません。どんな助けも大歓迎です。 datareaderを使用して複数のテーブルを読み取る必要がありますが、これは可能ですか?

46
muhammad kashif

これにより、タスクが終了すると接続、データリーダー、およびコマンドが閉じられるため、これを試してください。

また、このif(reader.NextResult())のようにチェックして、次の結果があることを確認します。

using (SqlConnection connection = new SqlConnection("connection string here"))
{
    using (SqlCommand command = new SqlCommand
           ("SELECT Column1 FROM Table1; SELECT Column2 FROM Table2", connection))
    {
        connection.Open(); 
        using (SqlDataReader reader = command.ExecuteReader())
        {
            while (reader.Read())
            {
                MessageBox.Show(reader.GetString(0), "Table1.Column1");
            }

            if(reader.NextResult())
            {
               while (reader.Read())
              {
                MessageBox.Show(reader.GetString(0), "Table2.Column2");
              }
            }
        }
    }
}
56
Pranay Rana

この問題を再現しようとしました(また、以前にリーダーで複数のテーブルを使用したことがないため)。しかし、期待どおりに機能するため、関連するコードを省略したと想定しています。

これが私のテストコードです。

using (var con = new SqlConnection(Properties.Settings.Default.ConnectionString))
{
    using (var cmd = new SqlCommand("SELECT TOP 10 * FROM tabData; SELECT TOP 10 * FROM tabDataDetail;", con))
    {
        int rowCount = 0;
        con.Open();
        using (IDataReader rdr = cmd.ExecuteReader())
        {
            while (rdr.Read())
            {
                String object1 = String.Format("Object 1 in Row {0}: '{1}'", ++rowCount, rdr[0]);
            }
            if (rdr.NextResult())
            {
                rowCount = 0;
                while (rdr.Read())
                {
                    String object1 = String.Format("Object 1 in Row {0}: '{1}'", ++rowCount, rdr[0]);
                }
            }
        }
    }
}
12
Tim Schmelter

Pranay Ranaの答えに基づいて作成したのは、できるだけ小さくするのが好きだからです。

string rslt = "";
using (SqlDataReader dr = cmd.ExecuteReader())
{
    do
    {
        while (dr.Read())
        {
            rslt += $"ReqID: {dr["REQ_NR"]}, Shpr: {dr["SHPR_NR"]}, MultiLoc: {dr["MULTI_LOC"]}\r\n";
        }
    } while (dr.NextResult());
}
0
tolsen64