データベーステーブルからテキストの説明を取得してテキストファイルに保存することを目的としたコードブロックがあります。次のようになります(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%一貫しているようには見えません。過去に例外をスローしたデータが突然機能する場合があります。
getItemsCommandでID、ITEMDESCRIPTION FROM ITEMSを選択して、2番目のクエリをスキップしなかった理由を疑問に思う人もいるでしょう。実際、最初はそのようにしましたが、getItemsCommand.GetString()で同じエラーが発生していました。データセットが大量のメモリを使用している可能性があり、それがエラーの原因である可能性があります。そこで、この方法を試して、役立つかどうかを確認することにしました。そうではありませんでした。なぜこれが起こっているのか誰かが知っていますか?
ちなみに、IDはINTで、ITEMDESCRIPTIONはVARCHAR(32000)列です。違いがある場合、データベースはBorland Interbase 6.0(Ick!)です。
編集:例外がスローされた場所を説明するときに間違った行を指定しました!! ARGH !! 修正されました。また、私はこれまでに提案されたものを試しましたが、それらは役に立ちませんでした。ただし、データベース内の非常に古いレコードのみがこのエラーの原因であることがわかりました。これは奇妙なことです。過去5年間に挿入されたレコードのみをプルするようにクエリを変更しても、問題はありません。誰かが私にこれはエンコーディング変換の問題かそのようなものかもしれないと提案しましたか?
更新:解決しました。この問題は、信頼性の低いデータベースソフトウェアのODBCドライバーのバグであることが判明しました。他のドライバーとの回避策で問題が修正されました。