MyDBHelper 建構子傳遞 version = 1 固定不變,修改表結構 (如加欄位) 時 onUpgrade 不會被呼叫,導致實際表結構與代碼預期不符,更新/刪除/查詢 SQL 執行失敗卻被 catch 吞掉。
public class MyDBHelper extends SQLiteOpenHelper {
private static final int DB_VERSION = 2; // 修改表結構時 +1
public MyDBHelper(Context context) {
super(context, "mvdb.db", null, DB_VERSION);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldV, int newV) {
if (oldV < 2) {
db.execSQL("ALTER TABLE user ADD COLUMN birthday TEXT;");
}
// 後續版本繼續加 if (oldV < 3) ...
}
}
public class UserDao {
private MyDBHelper helper;
public UserDao(Context ctx) { helper = new MyDBHelper(ctx); }
public long insert(String code, String name, String birth) {
SQLiteDatabase db = helper.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put("ecode", code);
cv.put("ename", name);
cv.put("ebirth", birth);
return db.insert("user", null, cv);
}
public int update(String code, String name, String birth) {
SQLiteDatabase db = helper.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put("ename", name);
cv.put("ebirth", birth);
return db.update("user", cv, "ecode=?", new String[]{code});
}
public int delete(String code) {
SQLiteDatabase db = helper.getWritableDatabase();
return db.delete("user", "ecode=?", new String[]{code});
}
public List query(String keyword) {
SQLiteDatabase db = helper.getReadableDatabase();
String sql = "SELECT * FROM user WHERE ecode LIKE ? OR ename LIKE ? OR ebirth LIKE ?";
String kw = "%" + keyword + "%";
Cursor c = db.rawQuery(sql, new String[]{kw, kw, kw});
List list = new ArrayList<>();
while (c.moveToNext()) {
list.add(new User(c.getString(0), c.getString(1), c.getString(2)));
}
c.close();
return list;
}
}
UserDao dao = new UserDao(this);
// 新增
dao.insert(code, name, birth);
// 更新
dao.update(code, name, birth);
// 刪除
dao.delete(code);
// 查詢
List list = dao.query(keyword);
// 綁定 ListView
ArrayAdapter adapter = new ArrayAdapter<>(this,
android.R.layout.simple_list_item_1, list);
listView.setAdapter(adapter);
insertData:db.execSQL("insert ... values(?,?)", new String[]{...}) 參數綁定錯誤,應用 ContentValues 或 db.insert。update SQL:where code='...'' 多一個單引號,且欄位名應為 ecode。query:Cursor 未關閉、ListAdapter 變數名衝突、ArrayAdapter 未設定給 ListView。資料庫版本號必須遞增觸發 onUpgrade,並將 CRUD 封裝為 DAO 類使用 ContentValues/insert/update/delete/query API,避免手拼 SQL 錯誤與資源洩漏。