我有一个带有数组的列表视图。我正在尝试将列表中选中的项目保存到我的数据库中,以便我可以回忆起下次启动该应用程序之前检查过的项目。
if (checkedTextView.isChecked()) {
db.execSQL("INSERT INTO list(found) VALUES (item.toString)");
if (score < 1119) {
score++;
} else {
score++;
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
levelFinishedConstraint.setVisibility(View.VISIBLE);
}
}, 1000);
}
} else {
db.execSQL("DELETE FROM list WHERE found = item.toString");
score = score - 1;
}
Cursor c = db.rawQuery("SELECT * FROM list", null);
int foundIndex = c.getColumnIndex("found");
if (c != null && c.moveToFirst()) {
do {
c.getString(foundIndex);
} while (c.moveToNext());
c.close(); }
String[] foundList = new String[foundIndex];
Log.i("DATABASE", c.getString(foundIndex));
按现状,当我现在打开页面而不是单击项目时,应用程序崩溃。以下是不断出现的关键错误
Process: com.example.woodlandwanderer, PID: 7370
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.woodlandwanderer/com.example.woodlandwanderer.levelOneActivity}: android.database.CursorIndexOutOfBoundsException: Index 2 requested, with a size of 2
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2778)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
Caused by: android.database.CursorIndexOutOfBoundsException: Index 2 requested, with a size of 2
at android.database.AbstractCursor.checkPosition(AbstractCursor.java:468)
at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:136)
at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:50)
at com.example.woodlandwanderer.levelOneActivity.onCreate(levelOneActivity.java:172)
at android.app.Activity.performCreate(Activity.java:7009)
at android.app.Activity.performCreate(Activity.java:7000)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
由于项目是我猜的对象,并且您希望它是StringResult,请尝试
db.execSQL("DELETE FROM list WHERE found = '" + item.toString + "'");
android.database.sqlite.SQLiteException: no such column: item.toString (code 1): , while compiling: INSERT INTO list(found) VALUES (item.toString)
该错误是由于item.toString没有用单引号引起来。可以通过使用:-
来解决db.execSQL("INSERT INTO list(found) VALUES ('item.toString')");
BUT您是否真的要在找到的列的值为“ item.toString”的地方插入一行。我对此非常怀疑,您最终可能会得到无数行,而且所有行都具有相同的可能无用的值。
您似乎想要的是:-
db.execSQL("INSERT INTO list(found) VALUES (?)", new String[]{item.toString});
然后将要插入的值将是item的toString方法返回的值。即?被Array中的项目替换(第一个?被数组的第一个元素替换,第二个?被第二个元素替换,依此类推)。在更换?也使用正确的外壳。
一种替代但不推荐的方法是使用:-
db.execSQL("INSERT INTO list(found) VALUES ('" + item.toString + "')");
Likewise,
db.execSQL("DELETE FROM list WHERE found = item.toString");
将有相同的问题,应该是:-
db.execSQL("DELETE FROM list WHERE found = ?",new String[]{item.toString});
public void execSQL(String sql)执行一个SQL语句不是SELECT或其他任何返回数据的SQL语句。
因此您可以使用execSQL()
的重载来插入或删除数据,但是您还必须将要传递的参数用单引号连接起来,因此这是不安全的,因为它会使您的应用程序对sql injection敞开大门。同样来自:https://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html#execSQL(java.lang.String,%20java.lang.Object%5B%5D)
public void execSQL(String sql,Object [] bindArgs)执行一次NOT SELECT / INSERT / UPDATE / DELETE的SQL语句。
因此execSQL()
是不是插入或删除行的推荐方法。而是通过在execSQL()
对象中提供列值和insert()
方法来使用方法insert()
:
ContentValues
您可以在此代码后检查delete()
变量delete()
,以获取是否插入成功。并删除该行:
ContentValues cv = new ContentValues();
cv.put("found", item.toString);
boolean inserted = db.insert("list", null, cv) > 0;
您可以在此代码后检查boolean
变量inserted
,以获取删除是否成功。为了使此代码正常工作,您必须正确初始化变量boolean deleted = db.delete("list", "found = ?", new String[] {item.toString}) > 0;
,表的名称必须为boolean
,列的名称为deleted
。另外,请确保db
返回要搜索的值。