如何将所选项目保存到SQLite

问题描述 投票:-1回答:3

我有一个带有数组的列表视图。我正在尝试将列表中选中的项目保存到我的数据库中,以便我可以回忆起下次启动该应用程序之前检查过的项目。

          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) 
java android sqlite
3个回答
0
投票

由于项目是我猜的对象,并且您希望它是StringResult,请尝试

db.execSQL("DELETE FROM list WHERE found = '" + item.toString + "'");

0
投票

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});

然后将要插入的值将是itemtoString方法返回的值。即被Array中的项目替换(第一个?被数组的第一个元素替换,第二个?被第二个元素替换,依此类推)。在更换?也使用正确的外壳。

一种替代但不推荐的方法是使用:-

db.execSQL("INSERT INTO list(found) VALUES ('" + item.toString + "')");

  • 不建议这样做,因为它可能会导致SQL注入。

Likewise

db.execSQL("DELETE FROM list WHERE found = item.toString");

将有相同的问题,应该是:-

db.execSQL("DELETE FROM list WHERE found = ?",new String[]{item.toString});

0
投票

发件人:https://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html#execSQL(java.lang.String)

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返回要搜索的值。

© www.soinside.com 2019 - 2024. All rights reserved.