3

我有一段代码旨在从数据库表中提取文本描述并将它们保存到文本文件中。它看起来像这样(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();

此代码已成功将部分数据保存到 .txt 文件,但对于许多行,以下行会引发 AccessViolationException:

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

异常文本是“尝试读取或写入受保护的内存。这通常表明其他内存已损坏”。

该程序通常会在表的相同行上引发异常,但它似乎不是 100% 一致的。有时,过去抛出异常的数据会突然起作用。

毫无疑问,有些人想知道为什么我不只是在 getItemsCommand 中选择 ID、ITEMDESCRIPTION FROM ITEMS 并跳过第二个查询。实际上,我最初是这样做的,并且在使用 getItemsCommand.GetString() 时遇到了同样的错误。我担心数据集可能占用了太多内存,这可能是导致错误的原因。所以我决定尝试这种方法,看看它是否有帮助。它没有。有谁知道为什么会发生这种情况?

顺便说一句,ID 是一个 INT 并且 ITEMDESCRIPTION 是一个 VARCHAR(32000) 列。如果有什么不同,数据库是 Borland Interbase 6.0 (Ick!)

编辑:在描述抛出异常的位置时,我给出了错误的行!啊!!现在修好了。另外,到目前为止,我已经尝试了建议的方法,但它们没有帮助。但是,我发现只有数据库中非常旧的记录导致了这个错误,这很奇怪。如果我将查询更改为仅提取过去 5 年插入的记录,则没有问题。有人向我建议这可能是编码转换问题或类似的问题?

更新:解决了。这个问题原来是我们不太可靠的数据库软件的 ODBC 驱动程序中的一个错误。使用其他驱动程序的解决方法解决了该问题。

4

2 回答 2

1

在这里黑暗中拍摄...

Try executing your reader, saving your result (maybe in an array or list), and making sure the reader is closed before executing or preparing the next command. You may even want to go extreme and put your getItemsCommand construction inside a using block so you know that it has no resources open before you execute your next command...

于 2008-10-23T02:27:03.093 回答
1

It could be a bug in the ODBC driver you are using. What driver is it? What is your connection string?

于 2008-10-23T06:21:32.043 回答