如何从SQLite表取值且避免抛出NullPointerException错误?
你的NullPointerException问题分析与修复方案
我一眼就看到几个会导致你出现NullPointerException或者查询失败的问题,咱们一个个拆解:
1. SQL语句的字符串拼接错误(最核心原因)
你直接把字符串类型的subject和level拼进SQL里,却没给它们加单引号!比如如果subject是"English",你的SQL会变成:
SELECT * FROM subjects_table WHERE subject_col = English AND level_col = Beginner
数据库会把English当成列名而不是字符串值,这会直接导致查询失败,返回的subjectCursor要么是空的,要么根本没有匹配的记录,后续调用getString自然会报错。
更安全的做法是用参数化查询(还能避免SQL注入),或者至少给字符串值加单引号(但参数化是更推荐的最佳实践)。
2. Cursor没有定位到有效记录
就算查询到了数据,Cursor默认的位置是在第一条记录的前面,直接调用getString肯定会出错,必须先调用moveToFirst()来确认是否有有效记录。
3. 没有处理空Cursor和列名不匹配的情况
- 如果查询没有结果,
subjectCursor.moveToFirst()会返回false,这时不能继续操作Cursor - 列名的大小写要和数据库里的完全一致!比如你写的是
"ID",但数据库里可能是小写的"id",这时候getColumnIndex("ID")会返回-1,调用getString(-1)也会抛出异常。
4. 数据库资源没有关闭
使用完SQLiteDatabase和Cursor后没有关闭,会造成内存泄漏,也可能引发其他异常。
修复后的代码示例
public String getSubjectId(String subject, String level) { String id = null; SQLiteDatabase db = null; Cursor subjectCursor = null; try { db = this.getWritableDatabase(); // 使用参数化查询,避免拼接错误和SQL注入 String query = "SELECT ID FROM " + SUBJECTS_TABLE_NAME + " WHERE " + SUBJECTS_COL_2 + " = ? AND " + SUBJECTS_COL_3 + " = ?"; subjectCursor = db.rawQuery(query, new String[]{subject, level}); // 检查是否有有效记录 if (subjectCursor != null && subjectCursor.moveToFirst()) { // 先确认列索引有效,再获取值 int idColumnIndex = subjectCursor.getColumnIndex("ID"); if (idColumnIndex != -1) { id = subjectCursor.getString(idColumnIndex); } } } finally { // 关闭Cursor和数据库资源,避免内存泄漏 if (subjectCursor != null) { subjectCursor.close(); } if (db != null) { db.close(); } } return id; }
额外建议
- 永远用参数化查询(
?占位符)来处理动态的SQL条件,不要直接拼接字符串,这是SQLite开发的标准规范 - 操作Cursor前一定要做非空和有效性检查
- 列名建议用常量定义,比如
public static final String COLUMN_ID = "id";,避免手动拼写错误
内容的提问来源于stack exchange,提问作者Roonil
相关产品推荐
相关产品推荐

