Hello Stack社区。 p>
我一直在开发一个与SQLite数据库进行大量交互的应用程序。我需要在DB中插入一个BLOB声音。我想我是这样做的,就像这样:
byte[] fileContent = getSoundInBytes(filesDir+item.getListItemId());
ContentValues values = new ContentValues();
values.put("FileId", item.getContentFileId());
values.put("Content", fileContent);
long x = db.insert("Files", null, values);
“x”的值是精确的,它恰好是DB中序列中的正确数字。
但是......奇怪的是,当我试图查看记录是否存在时,它表示它不在那里。查询如下:
public boolean isIDPresentInFiles(String fileId)
{
boolean isIdPresent = false;
String query = "SELECT Count(FileId) as Count FROM Files " +
" where FileId = "+fileId;
Cursor c = db.rawQuery(query, null);
if (c.moveToFirst())
{
do{
isIdPresent = c.getInt(c.getColumnIndex("Count"))>0;
}while(c.moveToNext());
}
c.close();
return isIdPresent;
}
所以“isIdPresent”返回false。不要担心数据库关闭,因为我在FOR循环结束时单独执行,因为我不想通过在循环的每个循环中打开和关闭连接来锁定数据库。
让我感到惊讶的是,如果我使用Mozilla sqlite管理器直接在DB中执行查询,则返回“True”(Count大于0)。
Pffff真的很累这个问题。我为这项任务编写了大量代码,而不是被这种不知道的,奇怪的东西所阻挡,不想采取正确的方式。
编辑:这是一个日志:
07-20 16:46:55.123: E/file dir(11086): /data/data/package/files/sounds/tmp/X'635B35811DF5C148A61A5651FFF79C97BB5E'/
07-20 16:46:55.183: E/AndroidRuntime(11086): FATAL EXCEPTION: main
07-20 16:46:55.183: E/AndroidRuntime(11086): Process: package, PID: 11086
07-20 16:46:55.183: E/AndroidRuntime(11086): android.database.sqlite.SQLiteConstraintException: column FileId is not unique (code 19)
07-20 16:46:55.183: E/AndroidRuntime(11086): at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
07-20 16:46:55.183: E/AndroidRuntime(11086): at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:782)
07-20 16:46:55.183: E/AndroidRuntime(11086): at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:788)
07-20 16:46:55.183: E/AndroidRuntime(11086): at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:86)
07-20 16:46:55.183: E/AndroidRuntime(11086): at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1469)
07-20 16:46:55.183: E/AndroidRuntime(11086): at android.database.sqlite.SQLiteDatabase.insertOrThrow(SQLiteDatabase.java:1365)
07-20 16:46:55.183: E/AndroidRuntime(11086): at package.db.AllEntityDBHandler.insertNewLanguage(AllEntityDBHandler.java:776)
07-20 16:46:55.183: E/AndroidRuntime(11086): at package.fragments.FragmentNewLanguage$3.onClick(FragmentNewLanguage.java:125)
07-20 16:46:55.183: E/AndroidRuntime(11086): at android.view.View.performClick(View.java:4438)
07-20 16:46:55.183: E/AndroidRuntime(11086): at android.view.View$PerformClick.run(View.java:18422)
07-20 16:46:55.183: E/AndroidRuntime(11086): at android.os.Handler.handleCallback(Handler.java:733)
07-20 16:46:55.183: E/AndroidRuntime(11086): at android.os.Handler.dispatchMessage(Handler.java:95)
07-20 16:46:55.183: E/AndroidRuntime(11086): at android.os.Looper.loop(Looper.java:136)
07-20 16:46:55.183: E/AndroidRuntime(11086): at android.app.ActivityThread.main(ActivityThread.java:5001)
07-20 16:46:55.183: E/AndroidRuntime(11086): at java.lang.reflect.Method.invokeNative(Native Method)
07-20 16:46:55.183: E/AndroidRuntime(11086): at java.lang.reflect.Method.invoke(Method.java:515)
07-20 16:46:55.183: E/AndroidRuntime(11086): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
07-20 16:46:55.183: E/AndroidRuntime(11086): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
07-20 16:46:55.183: E/AndroidRuntime(11086): at dalvik.system.NativeStart.main(Native Method)
此日志属于在检查数据库中是否存在id后执行的方法,并且检查返回“False”,因此这意味着该记录不存在,但奇怪的是当另一个方法尝试插入记录相信时它没有出现,DB说它就在那里。
答案 0 :(得分:0)
嗯,我认为这个项目第一次运行时工作正常。当您第二次运行它时会出错,因为FileId
是您的primary key
,而ID为1的行已经插入到您的数据库中。 From here
要消除错误:
1) uninstall the app and run it again
2) Don't make FileId as primary key
3) Catch the exception and handle it yourself
您在查询中错过了单引号(因为 fileId 是字符串),所以请使用
String query = "SELECT Count(FileId) as Count FROM Files where FileId = '" + fileId + "'";
但推荐的解决方案是使用参数化查询
Cursor c = db.query("Files", new String[] { "FileId" }, "FileId" + "=?",
new String[] { fileId }, null, null, null, null);
并将 isIdPresent 检查为
if (c!= null && c.getCount() > 0) {
isIdPresent = true;
}
c.close();
return isIdPresent;