代码之家  ›  专栏  ›  技术社区  ›  Joshua Carmody

为什么OdbcCommand.ExecuteScalar()会引发AccessViolationException?

  •  3
  • Joshua Carmody  · 技术社区  · 17 年前

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

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

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

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

    顺便说一下,ID是一个INT,itemsdescription是一个VARCHAR(32000)列。如果有什么区别的话,数据库是Borland Interbase 6.0(Ick!)

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

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

    2 回复  |  直到 17 年前
        1
  •  1
  •   to StackOverflow    17 年前

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

        2
  •  1
  •   Dave Markle    17 年前

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

    推荐文章