Java から Windows 32 ビットの Access データベースにデータを書き込んでいます。レコードを書き込むときは、行 ID/主キーを取得して、a) 必要に応じてレコードを簡単に更新し、b) 他のデータをそのレコードに相互参照できるようにする必要があります。
C で似たようなことをすると、新しいレコードを書き込み、同時に行 ID を取得できる更新可能なカーソルを作成できました。Java では、これを行うことができるように見えますが、次のコードで例外がスローされます。
con = openAccessDatabase();
String selectString = "SELECT ID, RunCount FROM SpeedTable";
try {
PreparedStatement selectStatement = con.prepareStatement(selectString,
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
ResultSet idResult = selectStatement.executeQuery();
int id;
for (int i = 0; i < nWrites; i++) {
idResult.moveToInsertRow();
idResult.updateObject(1, null); // this line makes no difference whatsoever !
idResult.updateInt(2, i);
idResult.insertRow(); // throws java.sql.SQLException: [Microsoft][ODBC Microsoft Access Driver]Error in row
id = idResult.getInt(1);
}
selectStatement.close();
} catch (SQLException e) {
e.printStackTrace();
}
私ができる唯一のことは、新しいレコードを書き込んでから、別のクエリを実行して行 ID を取得することです...
String insertString = "INSERT INTO SpeedTable (RunCount) VALUES (?)";
String idString = "SELECT ID FROM SpeedTable ORDER BY ID DESC";
//
try {
ResultSet idResult = null;
PreparedStatement preparedStatement, idStatement;
preparedStatement = con.prepareStatement(insertString,
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY);
idStatement = con.prepareStatement(idString,
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY);
for (int i = 0; i < nWrites; i++) {
// write the data into the database
preparedStatement.setInt(1, i);
preparedStatement.execute();
// re-run the query to get the index back from the database.
idResult = idStatement.executeQuery();
idResult.next();
int lastIndex = idResult.getInt(1);
idResult.close();
}
これは機能しますが、テーブルに数十から数千のレコードが含まれていると、信じられないほど遅くなります。プログラムの 2 つの部分が同時に書き込みを開始すると、間違った ID が返される危険性もあります (可能性は低いですが、不可能ではありません)。
少なくとも 1 つの提案は、Java を使用しないか、Access を使用しないかのいずれかであることはわかっていますが、それらはオプションではありません。これは無料のオープン ソース ソフトウェア パッケージの一部でもあるので、何かにお金を払うのは気が進まない. アプリケーションに必要な基本機能を提供する独自の C JNI インターフェースを作成することは、さらに魅力的ではありません。