SQLite 查询错误,onItemClick 导致应用崩溃

Posted

技术标签:

【中文标题】SQLite 查询错误,onItemClick 导致应用崩溃【英文标题】:SQLite query wrong, onItemClick making the app crash 【发布时间】:2019-09-24 13:23:47 【问题描述】:

我有一个列表视图,我用通过 SQLite 在数据库中输入的名称填充它。当我单击其中一个名称时,应用程序崩溃。

如果您能找到问题,我将不胜感激。谢谢!

我添加了当我单击列表中的名称时出现的 logcat 部分。 COL0 = "ID" 和 COL1 = "名称"。

OnClick 方法:

listView.setOnItemClickListener(new AdapterView.OnItemClickListener() 
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) 
                String name = adapterView.getItemAtPosition(i).toString();
                Log.e(TAG, name);
                Log.e(TAG, "" + i);
                Cursor player = dbHelper.getItemID(name);  //this is line 51 -> see logcat
                int itemID = -1;
                while(player.moveToNext())
                    itemID = player.getInt(0);
                if(itemID > -1) 
                    Intent intent = new Intent(PlayersList.this, PlayerCharacters.class);
                    intent.putExtra("id", itemID);
                    intent.putExtra("name", name);
                    startActivity(intent);
                 else Toast.makeText(PlayersList.this, "No ID associated with that name.", Toast.LENGTH_SHORT).show();
            
        );
    

数据库类中的getItemID()方法:

public Cursor getItemID(String name) 
        SQLiteDatabase db = this.getWritableDatabase();
        String query = "SELECT " + COL0 + " FROM " + TABLE_NAME + " WHERE " + COL1 + " = " + name;
        Cursor data = db.rawQuery(query, null);  //this is line 62 -> see logcat
        return data;
    

单击一个项目(列表中的名称)时得到的错误日志:

D/AbsListView: onTouchUp() mTouchMode : 0
E/PlayersListActivity: Eu
    3
E/SQLiteLog: (1) no such column: Eu
D/androidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.characters, PID: 30728
    android.database.sqlite.SQLiteException: no such column: Eu (code 1): , while compiling: SELECT ID FROM PlayersTable WHERE Name = Eu
    #################################################################
    Error Code : 1 (SQLITE_ERROR)
    Caused By : SQL(query) error or missing database.
        (no such column: Eu (code 1): , while compiling: SELECT ID FROM PlayersTable WHERE Name = Eu)
    #################################################################
        at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
        at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:1096)
        at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:661)
        at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
        at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:59)
        at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37)
        at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:44)
        at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1746)
        at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1685)
        at com.example.characters.DatabaseHelper.getItemID(DatabaseHelper.java:62)  //---->here
        at com.example.characters.PlayersList$1.onItemClick(PlayersList.java:51)   //----->here
        at android.widget.AdapterView.performItemClick(AdapterView.java:350)
        at android.widget.AbsListView.performItemClick(AbsListView.java:1683)
        at android.widget.AbsListView$PerformClick.run(AbsListView.java:4094)
        at android.widget.AbsListView$10.run(AbsListView.java:6583)
        at android.os.Handler.handleCallback(Handler.java:789)
        at android.os.Handler.dispatchMessage(Handler.java:98)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6944)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
Application terminated.

【问题讨论】:

【参考方案1】:

字符串值name必须用单引号括起来:

String query = "SELECT " + COL0 + " FROM " + TABLE_NAME + " WHERE " + COL1 + " = '" + name + "'";

如果没有这些单引号,字符串值 name 将被视为列名,并且由于表中不存在这样的列,因此应用程序崩溃并出现如下错误:

no such column: Eu

但是将参数传递给查询的安全且推荐的方法是:

String query = "SELECT " + COL0 + " FROM " + TABLE_NAME + " WHERE " + COL1 + " = ?";
Cursor data = db.rawQuery(query, new String[] name);

这样你就不必担心单引号,因为这将由方法rawQuery()处理。

【讨论】:

非常感谢!我明白它现在是如何工作的。祝你有美好的一天!

以上是关于SQLite 查询错误,onItemClick 导致应用崩溃的主要内容,如果未能解决你的问题,请参考以下文章

在循环Recyclerview android中捕捉中心onItemClick

在片段中与 onItemClick 斗争

SQLite3 INSERT 查询上的随机语法错误

Android间歇性错误onitemclick java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0

SQLite INSERT 和 DELETE 查询给出错误,但不是 SELECT 查询

我正在尝试学习 sqlite 查询,但不断收到此错误