Android中SQLite批量插入无报错但无数据返回问题求助
问题排查与解决方案
我一眼就看到了你代码里的核心问题——批量插入的逻辑完全错误,这就是你查询不到数据的根本原因。咱们一步步拆解问题并修正:
1. 核心错误:循环内未执行插入操作
你当前的代码中,while(rs.next())循环只是不断给同一个ContentValues对象赋值(每次都会覆盖之前的字段值),然后只在循环结束后调用了一次mDb.insert()。这会导致两种情况:
- 如果结果集有数据:最终只会插入最后一条记录(因为前面的字段值都被覆盖了)
- 如果结果集为空:完全没有数据被插入
修正方案:
方案一:每次循环新建ContentValues并插入
public void insertIntoDbLite(ResultSet rs) { mDb = mDbHelper.getWritableDatabase(); mDb.beginTransaction(); try { while (rs.next()) { // 每次循环新建ContentValues,避免覆盖之前的数据 ContentValues values = new ContentValues(); values.put("COL1", rs.getString("Col1_Val")); values.put("COL2", rs.getString("Col2_Val")); values.put("COL3", rs.getString("Col3_Val")); values.put("COL4", rs.getString("Col4_Val")); values.put("COL5", rs.getString("Col5_Val")); values.put("COL6", rs.getString("Col6_Val")); values.put("COL7", rs.getString("Col7_Val")); values.put("COL8", rs.getString("Col8_Val")); values.put("COL9", rs.getString("Col9_Val")); // 注意修正拼写错误 // 每次循环执行插入 mDb.insert("TABLE_1", null, values); } mDb.setTransactionSuccessful(); } catch(java.sql.SQLException e) { Log.e("Error in SQL",e.toString()); } catch(Exception ex) { Log.e("Error in transaction",ex.toString()); } finally { mDb.endTransaction(); mDb.close(); // 关闭数据库,避免资源泄漏 } }
方案二:用SQLiteStatement实现高效批量插入(推荐)
对于大量数据,这种方式比insert()更高效:
public void insertIntoDbLite(ResultSet rs) { mDb = mDbHelper.getWritableDatabase(); mDb.beginTransaction(); SQLiteStatement stmt = null; try { // 预编译插入语句 stmt = mDb.compileStatement("INSERT INTO TABLE_1 (COL1, COL2, COL3, COL4, COL5, COL6, COL7, COL8, COL9) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"); while (rs.next()) { // 绑定参数 stmt.bindString(1, rs.getString("Col1_Val")); stmt.bindString(2, rs.getString("Col2_Val")); stmt.bindString(3, rs.getString("Col3_Val")); stmt.bindString(4, rs.getString("Col4_Val")); stmt.bindString(5, rs.getString("Col5_Val")); stmt.bindString(6, rs.getString("Col6_Val")); stmt.bindString(7, rs.getString("Col7_Val")); stmt.bindString(8, rs.getString("Col8_Val")); stmt.bindString(9, rs.getString("Col9_Val")); // 执行插入 stmt.executeInsert(); // 清空绑定的参数,准备下一次循环 stmt.clearBindings(); } mDb.setTransactionSuccessful(); } catch(java.sql.SQLException | android.database.SQLException e) { Log.e("Insert Error", e.toString()); } finally { if (stmt != null) { stmt.close(); } mDb.endTransaction(); mDb.close(); } }
2. 次要问题:字段名拼写错误
你代码里写了values.put("COl9", rs.getString("Col9_Val"));,这里的键是COl9(大写O+小写l),而你的列名应该是COL9。虽然SQLite不区分大小写,但为了避免潜在问题,建议统一成COL9。
3. 删除数据时的数据库对象问题
删除表数据时你用了getReadableDatabase(),虽然execSQL可以在可读数据库上执行,但删除属于写操作,应该用getWritableDatabase()确保数据库处于可写状态:
mDb = mDbHelper.getWritableDatabase(); mDb.execSQL("DELETE FROM TABLE_1"); mDb.close(); // 记得关闭数据库
4. 资源泄漏问题:SQL Server连接与结果集未正确关闭
当前代码中,con.close()放在try块里,如果发生异常可能不会执行。建议用Java的try-with-resources语法自动关闭资源:
try (Connection con = connectionClass.CONN(); PreparedStatement statement = con.prepareStatement("Exec SelectAll '" + Param1+ "'"); ResultSet rs = statement.executeQuery()) { liteAdapter.insertIntoDbLite(rs); } catch (SQLException ex) { Log.e("SQL Server Error", ex.getMessage()); }
这样con、statement、rs会自动关闭,无需手动调用close()。
5. 验证插入结果
可以在插入后立即查询表数据,确认插入是否成功:
// 在调用insertIntoDbLite之后执行 SQLiteDatabase db = mDbHelper.getReadableDatabase(); Cursor cursor = db.query("TABLE_1", null, null, null, null, null, null); Log.d("Insert Result", "Total records in TABLE_1: " + cursor.getCount()); cursor.close(); db.close();
按照以上步骤修正后,你的批量插入逻辑就能正常工作,查询TABLE_1时就能看到数据了。
内容的提问来源于stack exchange,提问作者user7592671
相关产品推荐
相关产品推荐

