2008-10-23 2 views
3

У меня есть блок кода, предназначенный для вывода текстовых описаний из таблицы базы данных и сохранения их в текстовый файл. Похоже, это (C# .NET):Почему OdbcCommand.ExecuteScalar() бросает исключение AccessViolationException?

 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%. Иногда неожиданно срабатывают данные, которые в прошлом исключали исключение.

Некоторые люди, несомненно, задаются вопросом, почему я не просто SELECT ID, ITEMDESCRIPTION FROM ITEMS в getItemsCommand и пропустил второй запрос. На самом деле, я сделал это именно так, и я столкнулся с той же ошибкой с getItemsCommand.GetString(). Я боялся, что, возможно, набор данных занял слишком много памяти и, возможно, это вызвало ошибку. Поэтому я решил попробовать этот метод, чтобы узнать, поможет ли это. Это не так. Кто-нибудь знает, почему это может произойти?

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

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

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

ответ

1

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

+0

Это драйвер ODBC от Easysoft Interbase. Он настроен как системный DSN с именем «BVDATA2». Строка подключения в .NET - это просто «DSN = BVDATA2». –

+0

Это действительно было ошибкой с драйвером ODBC. –

1

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

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

+0

Пробовал, и это не помогло. –

+0

Да ... После того, как я услышал, что закрытие читателя не помогло, я определенно попытаюсь получить некоторую поддержку от продавца на этом ... –

Смежные вопросы