NPGSQL: потоковая передача результатов запроса Postgres? - PullRequest
2 голосов
/ 08 января 2010

У меня большая таблица (2 000 000 строк), и я хотел бы распечатать каждую запись на экране по одной без загрузки всей таблицы в память.

//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 x2:

из npgsql Предупреждение: существует известная проблема при вызове ExecuteReader и больших таблиц. В настоящее время Версия 1 Npgsql получает все данные из таблицы перед возвратом. Если в таких случаях у вас плохая производительность, вам может потребоваться использовать серверный курсор для пролистывания строк. Для этого вы можете использовать код, подобный следующему:

Ответы [ 4 ]

4 голосов
/ 08 января 2010

Npgsql2 теперь намного лучше обрабатывает большие наборы результатов. Он не загружает все данные в память. Таким образом, вам больше не нужно использовать курсор на стороне сервера.

Надеюсь, это поможет.

Франциско Фигейредо младший Npgsql Ведущий разработчик

2 голосов
/ 08 января 2010

Хорошо, похоже, это известная проблема с npgsql 1.0:

Обходной путь должен использовать серверный курсор:

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();
    }
  }
}
0 голосов
/ 10 февраля 2016

Чтобы распечатать всю таблицу с именем и значением столбца, используйте следующий код:

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("====================");
                    }
                }
            }
0 голосов
/ 16 февраля 2013

Самый простой способ сделать это:

COPY ( select * from Table) TO STDOUT

Проверьте синтаксис копирования, чтобы увидеть, как распечатать его в .csv или любом другом формате, если вам нужно ...

...