У меня есть блок кода, предназначенный для вывода текстовых описаний из таблицы базы данных и сохранения их в текстовый файл. Похоже, это (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 для нашего не очень надежного программного обеспечения для баз данных. Проблема была с обходным решением с другими драйверами.
Это драйвер ODBC от Easysoft Interbase. Он настроен как системный DSN с именем «BVDATA2». Строка подключения в .NET - это просто «DSN = BVDATA2». –
Это действительно было ошибкой с драйвером ODBC. –