Pergunta

Eu tenho uma grande mesa (2.000.000 linhas) e eu gostaria de imprimir cada registro para a tela, um de cada vez, sem carregar a tabela inteira na memória.

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

}

Assim como observado no código acima, o ExecuteReader () não continuará até que todo o conjunto é carregado na memória. Como faço para alterar esse comportamento para que os resultados são transmitidos?

Graças

ETA: Enquanto esta parece ser a lição de casa, não é. É apenas uma maneira mais fácil para descrever um problema que envolve a leitura de uma tabela inteira com uma única consulta, mas o processamento dos resultados de uma linha de cada vez.

ETA x2:

De Npgsql Aviso: Existe um problema conhecido ao chamar ExecuteReader e grandes mesas. Actualmente Version 1 de Npgsql recebe todos os dados da tabela antes de retornar. Se você está tendo mau desempenho em tais casos, você pode precisar usar um cursor de servidor de página através de linhas. Para isso, você pode usar um código como o seguinte:

Foi útil?

Solução 2

Ok, bem, parece que este é um problema conhecido com Npgsql 1.0:

A solução é usar um cursor de servidor:

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();
    }
  }
}

Outras dicas

Npgsql2 agora lida com grandes conjuntos de resultados muito melhores. Ele não carrega todos os dados na memória. Assim, você não precisa usar um cursor do lado do servidor mais.

Espero que ajude.

Francisco Figueiredo Jr. Npgsql desenvolvedor-chefe

A maneira mais fácil de fazer isso é:

COPY ( select * from Table) TO STDOUT

Verifique a sintaxe da cópia para ver como imprimi-lo no arquivo .csv ou qualquer outro formato, se você precisa ...

Para imprimir toda a tabela com o nome da coluna e utilização valor seguinte código:

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("====================");
                    }
                }
            }
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top