我有一段代码用于从数据库表中提取文本描述并将其保存到文本文件中。它看起来像这样(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中使用SELECT ID,ITEMDESCRIPTION FROM ITEMS而跳过第二个查询。实际上,我最初是这样做的,我遇到了与getItemsCommand.GetString()相同的错误。我担心数据集可能占用了太多内存,可能导致错误。所以我决定尝试这种方法来看看它是否会有所帮助。它没有。有谁知道为什么会发生这种情况?
顺便说一下,ID是一个INT,而ITEMDESCRIPTION是一个VARCHAR(32000)列。如果它有任何区别,数据库是Borland Interbase 6.0(Ick!)
编辑:我在描述抛出异常的位置时给出了错误的界限!!哎呀!现在修复了。此外,我已经尝试了目前为止建议的事情,但他们没有帮助。但是,我发现只有数据库中非常旧的记录才会导致此错误,这很奇怪。如果我将查询更改为仅拉取过去5年中插入的记录,则没有问题。有人向我建议这可能是编码转换问题或类似的问题吗?
更新:解决了它。对于我们不太可靠的数据库软件,问题结果证明是ODBC驱动程序中的一个错误。其他驱动程序的解决方法解决了这个问题。
答案 0 :(得分:1)
在黑暗中拍摄......
尝试执行阅读器,保存结果(可能在数组或列表中),并确保在执行或准备下一个命令之前关闭阅读器。您甚至可能想要极端化并将getItemsCommand构造放在一个使用块中,这样您就知道在执行下一个命令之前它没有打开资源...
答案 1 :(得分:1)
它可能是您正在使用的ODBC驱动程序中的错误。它的动力是什么?你的连接字符串是什么?