我正在尝试使用内容提供程序从SQLite数据库中删除一行,但我的代码会删除所有行。这就是我正在做的事情:
我正在通过这个uri:
内容://appfactory.app.dehleezcafe/category/1
“category”是表名,“1”是要删除的记录。
这是我在某处调用的删除代码:
// Delete category
this.getContentResolver().delete(
contentURI,
null,
null
);
contentURI等于uri通过。
在这里,ContentProvider类中的delete方法会发生什么:
rowsDeleted = db.delete(CategoryEntry.TABLE_NAME, selection, selectionArgs);
这将删除所有行而不是行“1”?这不是我想要的。我很感激任何建议。
这是我的合同:
public static final String CONTENT_AUTHORITY = "appfactory.app.dehleezcafe";
public static final Uri BASE_CONTENT_URI = Uri.parse("content://" + CONTENT_AUTHORITY);
public static final String PATH_CATEGORY = "category";
public static final String PATH_ITEM = "item";
Category BaseColumns类:
public static final class CategoryEntry implements BaseColumns {
public static final String TABLE_NAME = "category";
public static final String COLUMN_CATEGORY_NAME = "name";
public static final Uri CONTENT_URI =
BASE_CONTENT_URI.buildUpon().appendPath(PATH_CATEGORY).build();
public static final String CONTENT_TYPE =
ContentResolver.CURSOR_DIR_BASE_TYPE + "/" + CONTENT_AUTHORITY + "/" + PATH_CATEGORY;
public static Uri buildCategoryUri(long id) {
return ContentUris.withAppendedId(CONTENT_URI, id);
}
}
Item BaseColumns类
public static final class ItemEntry implements BaseColumns {
public static final String TABLE_NAME = "item";
public static final String COLUMN_TITLE = "title";
public static final String COLUMN_DESCRIPTION = "description";
public static final String COLUMN_PRICE = "price";
public static final String COLUMN_PHOTO = "photo";
// Column with the foreign key into the category table.
public static final String COLUMN_CATEGORY_KEY = "category_id";
public static final Uri CONTENT_URI =
BASE_CONTENT_URI.buildUpon().appendPath(PATH_ITEM).build();
public static final String CONTENT_TYPE =
ContentResolver.CURSOR_DIR_BASE_TYPE + "/" + CONTENT_AUTHORITY + "/" + PATH_ITEM;
public static Uri buildItemUri(long id) {
return ContentUris.withAppendedId(CONTENT_URI, id);
}
创建语句:
// Category table create statement
final String SQL_CREATE_CATEGORY_TABLE = "CREATE TABLE " + CategoryEntry.TABLE_NAME + " (" +
CategoryEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
CategoryEntry.COLUMN_CATEGORY_NAME + " TEXT NOT NULL, " +
" )";
// Item table create statement
final String SQL_CREATE_ITEM_TABLE = "CREATE TABLE " + ItemEntry.TABLE_NAME + " (" +
ItemEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
// the ID of the category entry associated with this item data
ItemEntry.COLUMN_CATEGORY_KEY + " INTEGER, " +
ItemEntry.COLUMN_NAME + " TEXT NOT NULL, " +
ItemEntry.COLUMN_DESCRIPTION + " TEXT NOT NULL, " +
ItemEntry.COLUMN_PRICE + " TEXT NOT NULL, " +
ItemEntry.COLUMN_PHOTO + " BLOB, " +
// Set up the category column as a foreign key to category table.
" FOREIGN KEY (" + ItemEntry.COLUMN_CATEGORY_KEY + ") REFERENCES " +
CategoryEntry.TABLE_NAME + " (" + CategoryEntry._ID + ") " +
" )";
// Constructor
public MenuSQLiteHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
内容提供商中的删除方法:
// Delete Method
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// Student: Start by getting a writable database
final SQLiteDatabase db = menuDbHelper.getWritableDatabase();
// Student: Use the uriMatcher to match the WEATHER and LOCATION URI's we are going to
// handle. If it doesn't match these, throw an UnsupportedOperationException.
final int matchVal = uriMatcher.match(uri);
int rowsDeleted = 0;
// This makes delete all rows return the number of rows deleted
if(selection == null)
selection = "1";
switch (matchVal) {
case ITEM:
rowsDeleted = db.delete(
MenuContract.ItemEntry.TABLE_NAME, selection, selectionArgs);
break;
case CATEGORY:
rowsDeleted = db.delete(
MenuContract.CategoryEntry.TABLE_NAME, selection, selectionArgs);
break;
case ITEM_WITH_CATEGORY:
rowsDeleted = db.delete(CategoryEntry.TABLE_NAME, selection, selectionArgs);
break;
default:
throw new UnsupportedOperationException("Unknown Uri: " + uri);
}
// A null value deletes all rows.
if(rowsDeleted != 0 ) {
getContext().getContentResolver().notifyChange(uri, null);
}
// Return the actual rows deleted
return rowsDeleted;
}
我可以识别案例,但没有成功删除一行。
修改
奇怪的是,我可以使用此代码从“item”表中删除特定列,没有任何问题:
// Delete items of a category
String[] selctionArg = {String.valueOf(id)};
this.getContentResolver().delete(
ItemEntry.CONTENT_URI,
ItemEntry.COLUMN_CATEGORY_KEY+"=?",
selctionArg
);
使用与“category”表相同的代码不会删除任何内容,并且在删除所有行而不是特定行之前使用代码
答案 0 :(得分:0)
尝试这种方式很有用
SQLiteDatabase db = this.getWritableDatabase();
int x = db.delete(MenuContract.ItemEntry.TABLE_NAME,
MenuContract.ItemEntry.ITEM_ID + " = ?",
new String[]{item_id});
System.out.println("number of rows deleted"+x);
db.close();
答案 1 :(得分:0)
我有一个解决方案,试一试!
注意我已对CATEGORY
案例进行了更正。并且您不会忘记用您的列名替换_id
。
// Delete Method
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// Student: Start by getting a writable database
final SQLiteDatabase db = menuDbHelper.getWritableDatabase();
// Student: Use the uriMatcher to match the WEATHER and LOCATION URI's we are going to
// handle. If it doesn't match these, throw an UnsupportedOperationException.
final int matchVal = uriMatcher.match(uri);
int rowsDeleted = 0;
// This makes delete all rows return the number of rows deleted
if(selection == null)
selection = "1";
switch (matchVal) {
case ITEM:
rowsDeleted = db.delete(
MenuContract.ItemEntry.TABLE_NAME, selection, selectionArgs);
break;
case CATEGORY:
String segmentnew = uri.getPathSegments().get(1);
if (TextUtils.isEmpty(selection)) {
selection = "_id=" + segmentnew;
} else {
selection = "_id=" + segmentnew + " AND (" + selection + ")";
}
rowsDeleted = db.delete(
MenuContract.CategoryEntry.TABLE_NAME, selection, selectionArgs);
break;
case ITEM_WITH_CATEGORY:
rowsDeleted = db.delete(CategoryEntry.TABLE_NAME, selection, selectionArgs);
break;
default:
throw new UnsupportedOperationException("Unknown Uri: " + uri);
}
// A null value deletes all rows.
if(rowsDeleted != 0 ) {
getContext().getContentResolver().notifyChange(uri, null);
}
// Return the actual rows deleted
return rowsDeleted;
}
希望这适合你!
答案 2 :(得分:0)
this.getContentResolver().delete(CategoryEntry.CONTENT_URI,CategoryEntry._ID + " = ?", new String[]{String.valueOf(id)});
将其与原始代码一起使用
答案 3 :(得分:0)
感谢大家。我能够解决问题。问题是我在列表视图中传递行的位置,因为它与SQLite数据库中的行的_id相同。仅当我们首先创建listview行并将它们存储在数据库中时才会这样,因为它们匹配。但是,当我们删除行时,listview行的位置会更改它们的值,并且不再有效在选择条件中作为sqlite中项目的_id传递,因为sqlite项目的_id保持不变并且不受列表视图中位置更改的影响。为了解决这个问题,我需要传递被点击项目的光标并从光标中提取项目的_id。 为简单起见,假设我想要在点击时删除项目:
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView adapterView, View view, int position, long id) {
Cursor cursor = (Cursor) adapterView.getItemAtPosition(position);
在类别片段的某处,我正在声明类别列的常量:
// These indices are tied to CATEGORY_COLUMNS. If FORECAST_COLUMNS changes, these
// must change.
static final int COL_CATEGORY_ID = 0;
然后我可以将光标传递到任何地方以提取要删除的项目的_id:
@Override
public void deleteItem(Uri contentURI, Cursor cursor) {
long id = cursor.getLong(CategoryFragment.COL_CATEGORY_ID);
// Delete items of a category
String[] selctionArg = {String.valueOf(id)};
// Delete category
getContentResolver().delete(
MenuContract.CategoryEntry.CONTENT_URI,
MenuContract.CategoryEntry._ID + "=?",
selctionArg
);
}