You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android SQLite插入前检查记录存在性时应用崩溃问题排查

看起来你遇到的是两个典型的SQL构建错误,咱们一步步来拆解解决:

首先看Logcat的两个关键报错:

  • SQL语法错误 near "FROMshashaWHEREid":这明显是SQL语句里的关键字和表名/列名之间没加空格,数据库根本认不出FROM、WHERE这些关键字了。
  • ID显示为[Ljava.lang.String;@cdbe7d7:这是因为你把一个String数组直接拼进了SQL语句里,数组的默认toString()会输出它的内存地址,而不是实际的ID值。

接下来咱们逐个解决,先给你修正后的核心代码示例:

1. 正确实现「检查电影ID是否存在」的方法(以MoviesDBHelper为例)

不要手动拼接带参数的SQL,用参数化查询既避免语法错误,又防止SQL注入:

public class MoviesDBHelper extends SQLiteOpenHelper {
    // ... 其他已有的代码,比如构造函数、onCreate等

    // 检查指定ID的电影是否已存在
    public boolean isMovieExists(String movieId) {
        SQLiteDatabase db = this.getReadableDatabase();
        boolean exists = false;

        // 用参数化的rawQuery,注意SQL语句里的空格!
        Cursor cursor = db.rawQuery(
            "SELECT COUNT(*) FROM " + MoviesContract.MovieEntry.TABLE_NAME + " WHERE " + MoviesContract.MovieEntry.COLUMN_MOVIE_ID + " = ?",
            new String[]{movieId} // 这里把ID作为参数传入,避免直接拼接
        );

        if (cursor.moveToFirst()) {
            int count = cursor.getInt(0);
            exists = count > 0;
        }

        cursor.close();
        db.close();
        return exists;
    }
}

或者用更安全的query()方法(推荐):

public boolean isMovieExists(String movieId) {
    SQLiteDatabase db = this.getReadableDatabase();
    String[] projection = {MoviesContract.MovieEntry.COLUMN_MOVIE_ID};
    String selection = MoviesContract.MovieEntry.COLUMN_MOVIE_ID + " = ?";
    String[] selectionArgs = {movieId};

    Cursor cursor = db.query(
        MoviesContract.MovieEntry.TABLE_NAME,
        projection,
        selection,
        selectionArgs,
        null,
        null,
        null
    );

    boolean exists = cursor.getCount() > 0;
    cursor.close();
    db.close();
    return exists;
}

2. 修正点击事件里的逻辑

确保你传入的是单个ID字符串,而不是数组:

// 假设这是你的收藏按钮点击事件
favoriteBtn.setOnClickListener(v -> {
    // 先获取正确的电影ID(比如从Intent或ViewModel里拿,确保是String类型)
    String targetMovieId = "12345"; // 替换成你实际获取ID的代码

    MoviesDBHelper dbHelper = new MoviesDBHelper(getApplicationContext());
    if (!dbHelper.isMovieExists(targetMovieId)) {
        // 不存在则插入
        ContentValues values = new ContentValues();
        values.put(MoviesContract.MovieEntry.COLUMN_MOVIE_ID, targetMovieId);
        // 补充其他电影字段,比如标题、海报地址等
        // values.put(MoviesContract.MovieEntry.COLUMN_TITLE, movieTitle);

        // 用ContentResolver插入(如果你用了ContentProvider)
        getContentResolver().insert(MoviesContract.MovieEntry.CONTENT_URI, values);
        Toast.makeText(this, "收藏成功", Toast.LENGTH_SHORT).show();
    } else {
        Toast.makeText(this, "该电影已在收藏列表中", Toast.LENGTH_SHORT).show();
    }
});

3. 额外检查点

  • 确认MoviesContract里的表名和列名拼写正确:比如你报错里的表名是shasha,要确保MoviesContract.MovieEntry.TABLE_NAME确实等于"shasha",列名id对应COLUMN_MOVIE_ID = "id"。
  • 如果是用ContentProvider的query方法,要确保在MoviesProvider里正确处理查询参数,不要在Provider里又犯了拼接SQL的错误。

错误原因复盘

  1. 语法错误根源:你之前写的SQL可能是类似"SELECT * FROM" + TABLE_NAME + "WHEREid=" + id,FROM和表名之间、WHERE和id之间都没有空格,导致数据库把FROMshashaWHEREid当成了一个无效的标识符,直接抛出语法错误。
  2. ID显示为数组地址:你可能把String[]类型的ID数组直接拼进了SQL,比如"WHEREid=" + idArray,数组的toString()默认输出[Ljava.lang.String;@xxx这种格式,这显然不是有效的ID值。

按上面的代码修正后,应该就能解决崩溃问题,正常实现「存在则不插入,不存在则插入」的逻辑了。

内容的提问来源于stack exchange,提问作者mh9

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:14:19