13

クエリを実行し、その結果をユーザーのローカル ハード ディスクに保存する必要がある C# のリモート SQL 接続があります。このオブジェクトが返すことができるデータの量はかなり多いため、データを効率的に格納する方法を考える必要があります。その前に、最初に結果全体をメモリに入れ、それを書き込むのは良い考えではないことを読んだことがあります。

私は現在、SQL結果データをDataTableに保存していますが、while(myReader.Read(){...} 以下で何かを行う方が良いと考えていますが、結果を取得するコードは次のとおりです。

          DataTable t = new DataTable();
            string myQuery = QueryLoader.ReadQueryFromFileWithBdateEdate(@"Resources\qrs\qryssysblo.q", newdate, newdate);
            using (SqlDataAdapter a = new SqlDataAdapter(myQuery, sqlconn.myConnection))
            {
                a.Fill(t);
            }

            var result = string.Empty;
    for(int i = 0; i < t.Rows.Count; i++)
    {
        for (int j = 0; j < t.Columns.Count; j++)
        {
            result += t.Rows[i][j] + ",";
        }


        result += "\r\n";
    }

これで、この巨大な結果文字列ができました。そして、私はデータテーブルを持っています。それを行うためのはるかに良い方法が必要ですか?

ありがとう。

4

8 に答える 8

21

あなたは正しい軌道に乗っています。ループを使用して、while(myReader.Read(){...}各レコードをループ内のテキスト ファイルに書き込みます。.NET フレームワークとオペレーティング システムは、効率的な方法でバッファーをディスクにフラッシュします。

using(SqlConnection conn = new SqlConnection(connectionString))
using(SqlCommand cmd = conn.CreateCommand())
{
  conn.Open();
  cmd.CommandText = QueryLoader.ReadQueryFromFileWithBdateEdate(
    @"Resources\qrs\qryssysblo.q", newdate, newdate);

  using(SqlDataReader reader = cmd.ExecuteReader())
  using(StreamWriter writer = new StreamWriter("c:\temp\file.txt"))
  {
    while(reader.Read())
    {
      // Using Name and Phone as example columns.
      writer.WriteLine("Name: {0}, Phone : {1}", 
        reader["Name"], reader["Phone"]);
    }
  }
}
于 2012-01-29T18:20:27.350 に答える
2

元のアプローチを維持すると、ここに簡単な勝利があります。

String を一時バッファとして使用する代わりに、StringBuilderを使用します。.append(String)これにより、 operator を使用する代わりに、関数を連結に使用できるようになります+=

演算子+=は特に非効率的であるため、ループに配置して (潜在的に) 何百万回も繰り返すと、パフォーマンスに影響します。

メソッドは元の.append(String)オブジェクトを破棄しないため、高速です

于 2016-07-28T10:33:02.000 に答える
2

ここでの最善の策は、を使用することであることに同意しますSqlDataReader。このようなもの:

StreamWriter YourWriter = new StreamWriter(@"c:\testfile.txt");
SqlCommand YourCommand = new SqlCommand();
SqlConnection YourConnection = new SqlConnection(YourConnectionString);
YourCommand.Connection = YourConnection;
YourCommand.CommandText = myQuery;

YourConnection.Open();

using (YourConnection)
{
    using (SqlDataReader sdr = YourCommand.ExecuteReader())
        using (YourWriter)
        {
            while (sdr.Read())
                YourWriter.WriteLine(sdr[0].ToString() + sdr[1].ToString() + ",");

        }
}

ループ内で、whileその行を、SqlDataReader.

于 2012-01-29T18:23:12.183 に答える
1

原因なしで応答オブジェクトを使用するresponse.Close()と、少なくとも一部のインスタンスでは、データを書き出すページの html がファイルに書き込まれます。接続を使用Response.Close()すると、途中で閉じられ、ファイルの生成中にエラーが発生する可能性があります。

を使用することをお勧めしますが、HttpApplication.CompleteRequest()これにより常に html がファイルの最後に書き込まれるように見えます。

ストリームを応答オブジェクトと組み合わせて試してみたところ、開発環境で成功しました。まだ本番環境で試していません。

于 2015-12-31T13:21:23.613 に答える
1

.CSVを使用して、 DataReaderによってデータベースからデータをエクスポートしました。私のプロジェクトでは、datareader を読み、手動で .CSV ファイルを作成します。ループで datareader を読み取り、行ごとにセル値を結果文字列に追加します。個別の列には「,」を使用し、個別の行には「\n」を使用します。最後に、結果の文字列をresult.csvとして保存しました。

この高性能拡張機能をお勧めします。私はそれをテストし、600,000 行を .CSV としてすばやくエクスポートしました。

于 2017-05-23T14:13:05.560 に答える