Npgsqlの:Postgresのクエリからの結果をストリーミング?
-
19-09-2019 - |
質問
私は大きなテーブル(2,000,000行)があると私はメモリにテーブル全体をロードせずに、一度に1つの画面に各レコードを印刷したいと思います。
//pseudo code
var cmd = new NpgSQLCommand();
cmd.CommandText = "SELECT * FROM mytable;"
IReader reader = cmd.ExecuteReader(); //blocks until the entire set is returned
while(reader.Read()) //ideally each call to read loads more results from the db.
{
// print record name
}
上記のコードで述べたように、全体のセットがメモリにロードされるまで、、のExecuteReader()は継続しません。結果がストリーミングされているので、どのように私は、この動作を変更できますか?
おかげ
ETA:これは宿題のように思えますが、そうではありません。これは、単一のクエリでテーブル全体を読んだが、時間で結果に行の処理が含ま問題を記述するだけの簡単な方法です。
ETA×2:
のNpgsqlから 警告:のExecuteReaderと大きなテーブルを呼び出すときに、既知の問題があります。 <ストライキ>は現在ストライキ>のNpgsqlのバージョン1を返す前にテーブルからすべてのデータを取得します。あなたはこのような場合に悪いパフォーマンスを経験している場合は、行をページにサーバーカーソルを使用する必要があります。そのために、あなたは次のようなコードを使用することができます:
解決 2
さて、うまくそれが見えます:
この問題を回避するには、サーバーカーソルを使用することです。
using System;
using System.Data;
using Npgsql;
public static class NpgsqlUserManual
{
public static void Main(String[] args)
{
NpgsqlConnection conn = new NpgsqlConnection("Server=127.0.0.1;Port=5432;User Id=joe;Password=secret;Database=joedata;");
conn.Open();
NpgsqlCommand command = new NpgsqlCommand("select version()", conn);
String serverversion;
try
{
serverversion = (String)command.ExecuteScalar();
Console.WriteLine("PostgreSQL server version: {0}", serverversion);
}
finally
{
conn.Close();
}
}
}
他のヒント
Npgsql2は今より良い大きな結果セットを処理します。これは、メモリにすべてのデータをロードしません。だから、あなたはもう、サーバー側カーソルを使用する必要はありません。
私はそれが役に立てば幸います。
フランシスコ・フィゲイレド・ジュニア Npgsqlのリードデベロッパー
これを行う最も簡単な方法はあります:
COPY ( select * from Table) TO STDOUT
...あなたがする必要がある場合は.csvまたは任意の他の形式で印刷する方法を参照してくださいコピーの構文を確認してください。
のコード次の列の名前と値を使用して、テーブル全体を印刷するには、次の
using (var conn = new NpgsqlConnection("Host=IPADDRESS;Username=USER;Password=PASS;Database=DBNAME;"))
{
conn.Open();
using (var cmd = new NpgsqlCommand())
{
cmd.Connection = conn;
cmd.CommandText = "SELECT * FROM TABLE_NAME";
StringBuilder str;
int count;
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
str = new StringBuilder();
count = 0;
while (count < reader.FieldCount) {
str.Append(reader.GetName(count) + ": " + reader.GetValue(count));
if ((count + 1) < reader.FieldCount)
{
str.Append(", ");
}
count++;
}
Console.WriteLine(str.ToString());
Console.WriteLine("====================");
}
}
}