You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

ContentResolver删除指定ID数据异常:误删全库数据求助

解决Content Provider删除指定ID数据时误删全部的问题

嘿,我看到你在使用Content Provider删除指定ID的数据行时踩了个坑——误删了整个数据库的数据,咱们来把这个问题捋清楚并修复它!

问题根源分析

从你给出的代码片段来看,问题出在CARD_WITH_ID分支的处理上:

  • 你只生成了"%s = ?"的筛选条件,但没有把解析出来的ID值传入selectionArgs数组,这会导致SQL语句里的占位符?没有对应的值,数据库无法正确匹配指定ID的行,甚至会因为条件无效而执行全表删除。
  • 如果原本传入了selection参数,直接替换成新的ID条件会丢失原有筛选逻辑,进一步加剧错误。

修复后的完整delete方法实现

@Override
public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
    SQLiteDatabase db = mDbHelper.getWritableDatabase();
    int rowsDeleted;

    switch(sUriMatcher.match(uri)) {
        case CARD:
            // 注意:这里如果selection为null就默认删除全部数据,如果你不想这样,直接用原selection即可
            selection = (selection == null) ? "1" : selection;
            rowsDeleted = db.delete(CardContract.CardEntry.TABLE_NAME, selection, selectionArgs);
            break;
        case CARD_WITH_ID:
            long id = ContentUris.parseId(uri);
            // 拼接原有筛选条件和ID条件,避免覆盖原有逻辑
            if (selection != null && !selection.isEmpty()) {
                selection = selection + " AND " + CardContract.CardEntry._ID + " = ?";
            } else {
                selection = CardContract.CardEntry._ID + " = ?";
            }
            // 把ID添加到selectionArgs数组中,确保占位符有对应值
            String[] newSelectionArgs;
            if (selectionArgs != null) {
                newSelectionArgs = Arrays.copyOf(selectionArgs, selectionArgs.length + 1);
                newSelectionArgs[selectionArgs.length] = String.valueOf(id);
            } else {
                newSelectionArgs = new String[]{String.valueOf(id)};
            }
            rowsDeleted = db.delete(CardContract.CardEntry.TABLE_NAME, selection, newSelectionArgs);
            break;
        default:
            throw new IllegalArgumentException("Unknown URI for delete operation: " + uri);
    }

    // 删除成功后通知ContentResolver数据已变更,触发UI更新
    if (rowsDeleted > 0) {
        Objects.requireNonNull(getContext()).getContentResolver().notifyChange(uri, null);
    }

    return rowsDeleted;
}

关键修复点说明

  • 正确拼接筛选条件:当已有外部传入的selection时,用AND将ID条件与原有条件结合,既保留原有筛选逻辑,又确保只删除指定ID的行。
  • 完善selectionArgs参数:把解析出的ID值添加到参数数组中,让SQL语句的占位符?能正确匹配到目标ID,避免条件失效。
  • 通知数据变更:删除完成后调用notifyChange,确保监听该URI的UI组件(如列表)能及时刷新数据。

额外注意事项

  • 如果你不想在CARD分支中默认删除全部数据,直接移除selection = (selection == null) ? "1" : selection;这行代码即可——当selection为null时,db.delete不会删除任何行。
  • 确认你的UriMatcher配置正确,CARD_WITH_ID的模式应该类似content://your.app.authority/cards/#,确保能正确解析出URI中的ID值。

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

火山引擎 最新活动