Почему OdbcCommand.ExecuteScalar () выбрасывает исключение AccessViolationException?

StackOverflow https://stackoverflow.com/questions/228274

Вопрос

У меня есть блок кода, предназначенный для извлечения текстовых описаний из таблицы базы данных и сохранения их в текстовом файле. Это выглядит так (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%. Иногда данные, которые генерировали исключение в прошлом, неожиданно работают.

Некоторые люди, несомненно, задаются вопросом, почему я не просто выбрал ID, ОПИСАНИЕ ИЗДЕЛИЯ ИЗ ЭЛЕМЕНТОВ в getItemsCommand и пропустил второй запрос. На самом деле, я сделал это изначально, и я столкнулся с той же ошибкой с getItemsCommand.GetString (). Я боялся, что, возможно, набор данных занимал слишком много памяти и, возможно, это вызывало ошибку. Поэтому я решил попробовать этот метод, чтобы посмотреть, поможет ли он. Это не так. Кто-нибудь знает, почему это может происходить?

Кстати, ID - это INT, а ITEMDESCRIPTION - это столбец VARCHAR (32000). Если это имеет какое-то значение, база данных Borland Interbase 6.0 (Ick!)

РЕДАКТИРОВАТЬ: я дал неправильную строку при описании, где было выброшено исключение! ARGH !! Исправлено сейчас. Кроме того, я попробовал предложенные вещи, но они не помогли. Однако я обнаружил, что только очень старые записи в базе данных вызывали эту ошибку, что странно. Если я изменю запрос на извлечение записей, вставленных за последние 5 лет, проблем не будет. Кто-то сказал мне, что это может быть проблема преобразования кодировки или что-то в этом роде?

Обновление: решено. Проблема оказалась в ошибке драйвера ODBC для нашего не очень надежного программного обеспечения для баз данных. Обходной путь с другими драйверами устранил проблему.

Это было полезно?

Решение

Это может быть ошибка в используемом вами драйвере ODBC. Какой это драйвер? Какая у вас строка подключения?

Другие советы

Здесь выстрел в темноте ...

Попробуйте запустить программу чтения, сохранить результаты (возможно, в массиве или списке) и убедиться, что программа чтения закрыта перед выполнением или подготовкой следующей команды. Возможно, вы даже захотите пойти крайне далеко и поместить свою конструкцию getItemsCommand в блок using, чтобы вы знали, что у нее нет открытых ресурсов, прежде чем вы выполните следующую команду ...

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top