我在一个我在wishlist应用程序中使用的SQLite数据库中有一个表。我希望能够存储在数据库中购买的商品的历史记录。愿望清单中的每个项目都有一个详细视图,其中包含"已购买"用户可以单击以指示已购买愿望清单中的项目的复选框。然后,我有一个单独的"历史"用户可以单击选项菜单中的选项,这将打开由数据库中的项填充的列表视图。
当我选中复选框"已购买"我已经能够获得复选框的监听器,使用它的名称将项目添加到数据库中。在其详细视图上,名称显示在数据库的历史列表视图中。但是当我取消选中该框时,我试图用来删除数据库中的行的sql命令不起作用。它用来给出一个错误,现在它什么都不做。我已经包含了帮助程序类和代码部分,我在主代码中使用其名称添加和删除项目。我想直接使用项目名称删除,而不是搜索ID号,然后查询删除它。我宁愿直接使用这个名字,因为我不担心删除重复项。我曾尝试阅读其他帖子和一些参考文献,但无法弄清楚我错过了什么。
PS。在删除语句sql我试过没有" ' "但是得到了错误。这样我一无所获。它只是没有从视图中删除它。
来自DBHelper的代码
public class DBHelper extends SQLiteOpenHelper {
private static final String DB_NAME = "goodthings2.db";
private static final int DB_VERSION = 2;
public static final String TABLE_THINGS = "things";
public static final String C_ID = "_id";
public static final String C_TITLE = "title";
public static final String C_PRICE = "price";
public static final String C_DATE = "date";
public DBHelper(Context context){
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
final String sqlCreateTablePeople =
"CREATE TABLE " + TABLE_THINGS +
"( " + C_ID + " integer primary key autoincrement, "
+ C_TITLE + " text not null );";
db.execSQL(sqlCreateTablePeople);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
final String sqlDropTablePeople = "DROP TABLE IF EXISTS " + TABLE_THINGS +
";";
db.execSQL(sqlDropTablePeople);
onCreate(db);
}
}
愿望清单项详细视图片段中的代码部分:
mPurchasedCheckBox.setOnCheckedChangeListener(
new OnCheckedChangeListener(){
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked){
mThing.setPurchased(isChecked);
//Toast.makeText(getActivity(),
mThing.getTitle().toString(), Toast.LENGTH_LONG).show();
//String name = mThing.getTitle().toString();
if(isChecked == true){
Toast.makeText(getActivity(), "isChecked = true",
Toast.LENGTH_LONG).show();
// add the new data to the db
DBHelper helper = new DBHelper(getActivity());
SQLiteDatabase db = helper.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(DBHelper.C_TITLE,
mThing.getTitle().toString());
//cv.put(DBHelper.C_PRICE,
mThing.getPrice().toString());
//cv.put(DBHelper.C_DATE,
mThing.getDate().toString());
//cv.put(DBHelper.C_ID, mThing.getId().toString());
db.insert(DBHelper.TABLE_THINGS, null, cv);
db.close();
}else{
Toast.makeText(getActivity(), "isChecked = false",
Toast.LENGTH_LONG).show();
/*SQLiteDatabase db = new
DBHelper(getActivity()).getWritableDatabase();
int rowsAffected = -1;
rowsAffected = db.delete(DBHelper.TABLE_THINGS,
DBHelper.C_ID + " = " + mThing.getId().toString(), null);
Toast.makeText(getActivity(), "rowsAffected = " +
rowsAffected, Toast.LENGTH_LONG).show();
db.close();*/
DBHelper helper = new DBHelper(getActivity());
SQLiteDatabase db = helper.getWritableDatabase();
db.execSQL("delete from " + DBHelper.TABLE_THINGS +
" where " + DBHelper.C_TITLE + " = " + " ' " + mThing.getTitle().toString() + " ' " );
}
}
});
答案 0 :(得分:1)
未正确构建条件参数:
DBHelper.C_TITLE + " = " + " ' " + mThing.getTitle().toString() + " ' " );
引号之间的空格将使参数在开头和结尾有额外的空格(例如'标题'而不是'标题',因此要删除的记录找不到。)
建议:不要通过构建这样的自定义SQL语句来删除行,而是使用SQLiteDatabase.delete()方法。如果需要,这将正确地转义参数。否则,您的应用将会展示给SQL injection。作为额外奖励,结果将告诉您删除了多少记录。