Pergunta

Eu tenho um bloco de código destina-se a puxar descrições de texto de uma tabela de banco de dados e salvá-los em um arquivo de texto. Parece que este (C # .NET):

        OdbcCommand getItemsCommand = new OdbcCommand("SELECT ID FROM ITEMS", databaseConnection);
        OdbcDataReader getItemsReader = getItemsCommand.ExecuteReader();
        OdbcCommand getDescriptionCommand = new OdbcCommand("SELECT ITEMDESCRIPTION FROM ITEMS WHERE ID = ?", databaseConnection);
        getDescriptionCommand.Prepare();
        while (getItemsReader.Read())
        {
            long id = getItemsReader.GetInt64(0);
            String outputPath = "c:\\text\\" + id + ".txt";
            if (!File.Exists(outputPath))
            {
                getDescriptionCommand.Parameters.Clear();
                getDescriptionCommand.Parameters.AddWithValue("id", id);
                String description = (String)getDescriptionCommand.ExecuteScalar();
                StreamWriter outputWriter = new StreamWriter(outputPath);
                outputWriter.Write(description);
                outputWriter.Close();
            }
        }
        getItemsReader.Close();

Este código salvou com sucesso uma parte dos dados para arquivos .txt, mas para muitas linhas, um AccessViolationException é lançada sobre a seguinte linha:

                String description = (String)getDescriptionCommand.ExecuteScalar();

O texto de exceção é "Tentativa de ler ou gravar memória protegida. Isso é muitas vezes uma indicação de que outra memória está corrompida".

O programa irá geralmente lançar a exceção nas mesmas linhas da tabela, mas não parece ser 100% consistente. Às vezes, dados que tinha jogado a exceção no passado, de repente trabalho.

Algumas pessoas são, sem dúvida, perguntando por que eu não basta selecionar ID, ITEMDESCRIPTION DE ITENS no getItemsCommand e ignorar a segunda consulta. Na verdade, eu fiz isso dessa forma, inicialmente, e eu estava encontrando o mesmo erro com getItemsCommand.GetString (). Eu estava com medo de que talvez o conjunto de dados foi ocupando muita memória e, talvez, que estava causando o erro. Então eu decidi tentar este método para ver se ele iria ajudar. Ele não o fez. Alguém sabe por que isso pode estar acontecendo?

A propósito, ID é um INT e ITEMDESCRIPTION é uma coluna VARCHAR (32000). Se faz alguma diferença, o banco de dados é Borland Interbase 6.0 (Ick!)

EDIT: Eu dei a linha errada ao descrever onde a exceção foi sendo jogado !! ARGH !! Corrigido agora. Além disso, eu tentei as coisas sugeridas até agora, mas eles não ajudam. No entanto, descobri que só muito antigos registros no banco de dados estavam causando esse erro, o que é estranho. Se eu mudar a consulta para apenas registros puxar inseridos nos últimos 5 anos, não há problemas. Alguém me sugeriu isso pode ser um problema de conversão de codificação ou algo parecido?

Update: resolveu. O problema acabou por ser um bug no driver ODBC para o nosso software de banco de dados não muito confiável. Uma solução com outros motoristas corrigiu o problema.

Foi útil?

Solução

Ele poderia ser um bug no driver ODBC que você está usando. O motorista é? Qual é a sua seqüência de conexão?

Outras dicas

Um tiro no escuro aqui ...

Tente executar o seu leitor, economizando o seu resultado (talvez em uma matriz ou lista), e certificando-se o leitor está fechado antes de executar ou preparar o próximo comando. Você pode até querer ir extrema e colocar a sua construção getItemsCommand dentro de um bloco usando para que você saiba que não tem recursos abertos antes de executar o próximo comando ...

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