J'ai un bloc de code destiné à extraire des descriptions de texte d'une table de base de données et à les enregistrer dans un fichier texte. Il ressemble à ceci (C# .NET):Pourquoi OdbcCommand.ExecuteScalar() lève une exception 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();
Ce code a réussi à sauver une partie des données Txt fichiers, mais pour de nombreuses lignes, un AccessViolationException est jeté sur la ligne suivante:
String description = (String)getDescriptionCommand.ExecuteScalar();
Le texte d'exception est "Tentative de lecture ou d'écriture de la mémoire protégée, ce qui indique souvent qu'une autre mémoire est corrompue".
Le programme lancera généralement l'exception sur les mêmes lignes de la table, mais il ne semble pas être cohérent à 100%. Parfois, les données qui avaient jeté l'exception dans le passé vont soudainement fonctionner.
Certaines personnes se demandent sans doute pourquoi je n'ai pas simplement SELECT ID, ITEMDESCRIPTION FROM ITEMS dans la commande getItemsCommand et ignorer la deuxième requête. En fait, je l'ai fait de cette façon initialement, et je rencontrais la même erreur avec getItemsCommand.GetString(). J'avais peur que peut-être l'ensemble de données prenait trop de mémoire et peut-être que cela causait l'erreur. J'ai donc décidé d'essayer cette méthode pour voir si cela aiderait. Ce n'est pas le cas. Est-ce que quelqu'un sait pourquoi cela pourrait se produire? Par ailleurs, ID est un INT et ITEMDESCRIPTION est une colonne VARCHAR (32000). Si cela fait une différence, la base de données est Borland Interbase 6.0 (Ick!)
EDIT: J'ai donné la mauvaise ligne en décrivant où l'exception était lancée !! ARGH !! Fixé maintenant En outre, j'ai essayé les choses suggérées jusqu'ici, mais elles n'ont pas aidé. Cependant, j'ai trouvé que seuls les enregistrements très anciens dans la base de données provoquaient cette erreur, ce qui est étrange. Si je change la requête pour ne tirer que les enregistrements insérés dans les 5 dernières années, il n'y a pas de problèmes. Quelqu'un m'a suggéré que cela pourrait être un problème de conversion d'encodage ou quelque chose comme ça?
Mise à jour: Résolu. Le problème s'est avéré être un bogue dans le pilote ODBC pour notre logiciel de base de données pas très fiable. Une solution de contournement avec d'autres pilotes a résolu le problème.
C'est le pilote ODBC Easysoft Interbase. Il est configuré en tant que DSN système nommé "BVDATA2". La chaîne de connexion dans .NET est juste "DSN = BVDATA2". –
Il a effectivement semblé être un bogue avec le pilote ODBC. –