为什么 OdbcCommand.ExecuteScalar() 会抛出 AccessViolationException?

Why is OdbcCommand.ExecuteScalar() throwing an AccessViolationException?

提问人:Joshua Carmody 提问时间:10/23/2008 最后编辑:Joshua Carmody 更新时间:7/30/2009 访问量:4123

问:

我有一个代码块,用于从数据库表中提取文本描述并将它们保存到文本文件中。它看起来像这样 (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驱动程序中的错误。使用其他驱动程序的解决方法解决了该问题。

ado.net ODBC C# .NET 异常

评论


答:

1赞 Dave Markle 10/23/2008 #1

在黑暗中开枪......

尝试执行读取器,保存结果(可能在数组或列表中),并确保读取器在执行或准备下一个命令之前已关闭。你甚至可能想走极端,把你的getItemsCommand构造放在一个using块中,这样你就知道在你执行下一个命令之前它没有打开的资源......

评论

0赞 Dave Markle 10/26/2008
是的。。。在听说关闭阅读器没有帮助后,我肯定会尝试从供应商那里获得一些支持......
1赞 Joe 10/23/2008 #2

这可能是您正在使用的 ODBC 驱动程序中的错误。它是什么驱动程序?您的连接字符串是什么?

评论

0赞 Joshua Carmody 10/24/2008
它是 Easysoft Interbase ODBC 驱动程序。它被设置为名为“BVDATA2”的系统 DSN。.NET 中的连接字符串只是“DSN=BVDATA2”。
0赞 Joshua Carmody 12/11/2008
事实上,这似乎是 ODBC 驱动程序的一个错误。