2017-01-03 3 views
0

Я пытаюсь удалить только одну строку из базы данных SQLite с помощью поставщика контента, но мой код удаляет все строки. Вот что я делаю:Удаление только одной строки в SQLite Использование ContentProvider

Я передаю этот URI:

содержание: //appfactory.app.dehleezcafe/category/1

Где "категория" имя таблицы и «1» - это запись для удаления.

Это мой код удаления, что я называю где:

// Delete category 
     this.getContentResolver().delete(
       contentURI, 
       null, 
       null 
     ); 

contentURI равен Ури прошел.

Вот что происходит в методе удаления в классе ContentProvider:

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"; 

Категория 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); 

    } 
} 

этого пункта 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; 
} 

я мог бы получить случаи распознан, но не имели успеха в удалении только один ряд.

EDIT

Странная вещь, что я могу удалить определенные столбцы из таблицы «пункт» без проблем с помощью этого кода:

// Delete items of a category 
     String[] selctionArg = {String.valueOf(id)}; 

     this.getContentResolver().delete(
       ItemEntry.CONTENT_URI, 
       ItemEntry.COLUMN_CATEGORY_KEY+"=?", 
       selctionArg 
       ); 

Используя тот же код " категория "не удаляет ничего и использует код перед удалением всех строк вместо определенной строки

ответ

0

Спасибо всем. Я смог решить проблему. Проблема заключалась в том, что я передаю позицию строки в виде списка, считая ее такой же, как строка _id в базе данных SQLite. Это справедливо только тогда, когда мы сначала создаем строки списка и сохраняем их в базе данных, потому что они совпадают. Тем не менее, когда мы удаляем строки, позиции столбцов listview меняют свои значения и больше не являются допустимыми для передачи в качестве элемента _id в элементе sqlite в критериях выбора, потому что элемент _id объекта sqlite остается таким же и не зависит от изменений позиции в списке , Чтобы решить эту проблему, мне нужно было передать курсор щелкнутого элемента и извлечь из него элемент _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 
    ); 
} 
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();   
+0

Благодаря человеку, он не работает теперь не удаляя ничего, и как будто я не нажав кнопку удалить – fullMoon

0

У меня есть одно решение для вас, попробуйте!

Примечание. Я внесла поправки в корпус CATEGORY. И ya не забудьте заменить _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; 
} 

Надеюсь, это сработает для вас!

+0

Оцените это, я заменил предложенный вами код и добавил CategoryEntry._ID + "=" вместо "_id =", но теперь он не удаляет ничего, как ничего не происходит. – fullMoon

+0

@fullMoon вы получаете правильное значение 'segmentnew'? вы отлаживали и проверяли ценность? –

+0

Да segmentnew возвращает позицию строки, которую я хочу удалить правильно, я не знаю, почему она ничего не удаляет и всегда возвращает 0 для «rowsDeleted» – fullMoon

0

this.getContentResolver().delete(CategoryEntry.CONTENT_URI,CategoryEntry._I‌​D + " = ?", new String[]{String.valueOf(id)});

использовать это с исходным кодом

+0

привет, теперь это не сработало, это не удаляет ничего – fullMoon

+0

sorry use 'CategoryEntry ._ID' –

+0

вы получаете categoryId из 'uri.getpathsegments(). Get (1)'? –