Pergunta

Eu tenho um arquivo de banco de dados que eu acredito foi criado com Clipper, mas não posso dizer com certeza (eu tenho arquivos .ntx para índices que eu entendo é que usos Clipper). Eu estou tentando criar um aplicativo # C que irá ler este banco de dados usando o namespace System.Data.OleDb.

Para a maior parte eu posso com sucesso ler o conteúdo das tabelas não é um campo que eu não posso. Este campo chamado CTRLNUMS que é definido como um tipo CHAR (750). Eu li vários artigos encontrados através de pesquisas do Google que sugerem campo maior do que 255 caracteres têm de ser lidos através de um processo diferente do que a atribuição normal a uma variável de cadeia. Até agora eu não tenho sido bem sucedido em uma abordagem que eu encontrei.

A seguir é um exemplo de código trecho que estou usando para ler a tabela e inclui duas opções que eu costumava ler o campo CTRLNUMS. Ambas as opções resultou em 238 caracteres a serem devolvidos, embora haja 750 caracteres armazenados no campo.

Aqui é a minha string de conexão:

Provider = Microsoft.Jet.OLEDB.4.0; Data Source = c: \ datadir; Extensão Propriedades = DBASE IV;

Alguém pode me dizer o segredo para ler campos maiores de um arquivo DBF?

using (OleDbConnection conn = new OleDbConnection(connectionString))
{
    conn.Open();

    using (OleDbCommand cmd = new OleDbCommand())
    {
        cmd.Connection = conn;
        cmd.CommandType = CommandType.Text;
        cmd.CommandText = string.Format("SELECT ITEM,CTRLNUMS FROM STUFF WHERE ITEM = '{0}'", stuffId);

        using (OleDbDataReader dr = cmd.ExecuteReader())
        {
            if (dr.Read())
            {
                stuff.StuffId = dr["ITEM"].ToString();

                // OPTION 1
                string ctrlNums = dr["CTRLNUMS"].ToString();

                // OPTION 2
                char[] buffer = new char[750];
                int index = 0;
                int readSize = 5;
                while (index < 750)
                {
                    long charsRead = dr.GetChars(dr.GetOrdinal("CTRLNUMS"), index, buffer, index, readSize);

                    index += (int)charsRead;

                    if (charsRead < readSize)
                    {
                        break;
                    }
                }
            }
        }
    }
}
Foi útil?

Solução

Você pode encontrar uma descrição da estrutura DBF aqui: http: // www. dbf2002.com/dbf-file-format.html

O que eu acho Clipper costumava fazer era modificar a estrutura do campo de modo que, em campos de caracteres, as casas decimais manteve o byte de alta ordem do tamanho, de modo tamanhos de campo de caracteres foram realmente 256 * Decimals + Size.

Talvez eu tenha uma classe C # que lê DBFS (nativamente, não ADO / DAO), poderia ser modificado para lidar com este caso. Deixe-me saber se você estiver interessado.

Outras dicas

Você ainda está procurando por uma resposta? É este um one-off trabalho ou algo que precisa ser feito regularmente?

Eu tenho um módulo Python que se destina principalmente para extrair dados de todos os tipos de arquivos DBF ... não ainda lidar com a length_high_byte = decimal_places corte, mas é uma mudança trivial. Eu ficaria muito feliz em (a) compartilhar isso com você e / ou (b) obter uma cópia de tal arquivo DBF para testar.

Adicionado mais tarde: recurso Extended-length adicionado, e testado contra arquivos que eu criei-me. Ofereça-se para compartilhar código com quem gostaria de testá-lo ainda está de pé. Ainda interessado em obter alguns arquivos "reais" eu mesmo para o teste.

3 sugestões que pode valer a pena um tiro ...

1 - uso Access para criar uma tabela vinculada ao arquivo DBF, então use .Net para bater a tabela no banco de dados de acesso em vez de ir direto para a DBF

.

2 - tentar o FoxPro provedor OLEDB

3 - analisar o arquivo DBF com a mão. Exemplo é aqui .

Meu palpite é que # 1 deve trabalhar o mais fácil, e # 3 vai lhe dar a oportunidade de afinar suas habilidades cussing. :)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top