Удаление строки в SQLite в Android

102

Это может быть глупый вопрос, но я новичок в SQLite и, похоже, не могу этого понять. У меня есть 1 таблица , которая имеет столбцы KEY_ROWID, KEY_NAME, KAY_LATITUDE, и KEY_LONGITUDE. Я хочу, чтобы пользователь мог выбрать один и удалить его; Может ли кто-нибудь дать мне направление, в котором я могу начать? Мой вопрос заключается в фактическом удалении строки с указанием только ее имени.

Соответствующий код:

public class BeaconDatabase {

    public static final String KEY_ROWID = "_id";
    public static final String KEY_NAME = "beacon_name";
    public static final String KEY_LATITUDE = "beacon_lat";
    public static final String KEY_LONGITUDE = "beacon_lon";

    private static final String DATABASE_NAME ="BeaconDatabase";
    private static final String DATABASE_TABLE ="beaconTable";
    private static final int DATABASE_VERSION = 1;

    private DbHelper helper;
    private final Context context;
    private SQLiteDatabase db;

    public BeaconDatabase(Context context) {
        this.context = context;
    }

    public BeaconDatabase open() {
        helper = new DbHelper(this.context);
        db = helper.getWritableDatabase();
        return this;
    }

    public void close() {
        helper.close();
    }

    public long createEntry(String name, Double lat, Double lon) {
        ContentValues cv = new ContentValues();
        cv.put(KEY_NAME, name);
        cv.put(KEY_LATITUDE, lat);
        cv.put(KEY_LONGITUDE, lon);
        return db.insert(DATABASE_TABLE, null, cv);
    }

    public void deleteEntry(long row) {

              // Deletes a row given its rowId, but I want to be able to pass
              // in the name of the KEY_NAME and have it delete that row.
              //db.delete(DATABASE_TABLE, KEY_ROWID + "=" + row, null);
    }

    public String getData() {
        String[] columns = { KEY_ROWID, KEY_NAME, KEY_LATITUDE, KEY_LONGITUDE };
        Cursor cursor = db.query(DATABASE_TABLE, columns, null, null, null, null, null);
        String result = "";

        int iRow = cursor.getColumnIndex(KEY_ROWID);
        int iName = cursor.getColumnIndex(KEY_NAME);
        int iLat = cursor.getColumnIndex(KEY_LATITUDE);
        int iLon = cursor.getColumnIndex(KEY_LONGITUDE);

        for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
            result += cursor.getString(iRow) + ": " + cursor.getString(iName) + " - " + cursor.getDouble(iLat) + " latitude " + cursor.getDouble(iLon) + " longitude\n";
        }

        return result;

    }

    private static class DbHelper extends SQLiteOpenHelper {

        public DbHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL("CREATE TABLE " +  DATABASE_TABLE + " (" + 
                    KEY_ROWID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
                    KEY_NAME + " TEXT NOT NULL, " +
                    KEY_LATITUDE + " DOUBLE, " +
                    KEY_LONGITUDE + " DOUBLE);"
            );
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);
            onCreate(db);
        }
    }
}
roboguy12
источник
иди с ответом @iDroid ... так как он будет работать для меня. Спасибо iDroid.

Ответы:

183

Вы можете попробовать вот так:

 //---deletes a particular title---
public boolean deleteTitle(String name) 
{
    return db.delete(DATABASE_TABLE, KEY_NAME + "=" + name, null) > 0;
}

или

public boolean deleteTitle(String name) 
{
    return db.delete(DATABASE_TABLE, KEY_NAME + "=?", new String[]{name}) > 0;
}
Шреяш Махаджан
источник
61
Ответ Виджая правильный, потому что это решение позволяет выполнять SQL-инъекцию, что является утечкой безопасности. Например: используйте значение аргумента имени: name = "TRUE; <any SQL command>;"=> «любая команда SQL» будет выполнена. Конечно, это не проблема, если для этой функции нет графического интерфейса.
bdevay
@bdevay Мой ответ касается фоновой задачи, которую мы выполнили с помощью запроса. Так что это не связано с пользовательским интерфейсом. Вам просто нужно предоставлять информацию максимально динамично, чтобы не было необходимости в безопасности. Если вы следуете ответу vijay, и кто-то выполняет обратное проектирование, вы можете получить информацию о таблице в базе данных и поле, которое вы обрабатываете. что я делаю прямо в запросе, поэтому нет шансов получить лук-порей.
Шрейаш Махаджан 01
@iDroid Explorer: конечно, если нет пользовательского ввода или другой возможности манипулирования внешними запросами, тогда риск безопасности не выше, чем с другим решением. Продолжение в следующем комментарии ...
bdevay 01
1
... Но я не согласен с частью вашего комментария, касающейся обратной инженерии. Вы должны где-то и каким-то образом определить свой запрос, что означает, что обратное проектирование всегда является возможной утечкой безопасности (даже в случае вашего решения), особенно в Java, даже если источник запутан. Это может только увеличить время взлома. С другой стороны, в рекомендации Google используются аргументы выбора, пожалуйста, проверьте эту статью: ссылка
bdevay 01
Я имею в виду концепцию отсутствия статического значения для любого метода или любой переменной. Это должно быть максимально динамично. Так что это более безопасно, чем статическое значение. В любом случае пользователю решать, насколько безопасным он / она хочет сделать свое приложение.
Шрейаш Махаджан 01
157

Попробуйте так, возможно, вы получите свое решение

String table = "beaconTable";
String whereClause = "_id=?";
String[] whereArgs = new String[] { String.valueOf(row) };
db.delete(table, whereClause, whereArgs);
Виджай
источник
58

лучше использовать whereargs;

db.delete("tablename","id=? and name=?",new String[]{"1","jack"});

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

delete from tablename where id='1' and name ='jack'

и использование функции удаления таким образом хорошо, потому что оно удаляет инъекции sql.

Энахи
источник
2
Не могли бы вы подробнее рассказать о своем ответе, добавив еще немного описания предлагаемого вами решения?
abarisone
1
Думаю, стоит использовать whereargs.
msysmilu 03
@Enkahi Это похоже на подготовленные операторы в SQLite? Раньше я использовал такой id=?синтаксис с PHP, и он очень похож на него.
GeekWithGlasses
17

Пока я не пойму ваш вопрос, вы хотите поставить два условия для выбора удаляемой строки. Для этого вам необходимо сделать:

public void deleteEntry(long row,String key_name) {

      db.delete(DATABASE_TABLE, KEY_ROWID + "=" + row + " and " + KEY_NAME + "=" + key_name, null);

      /*if you just have key_name to select a row,you can ignore passing rowid(here-row) and use:

      db.delete(DATABASE_TABLE, KEY_NAME + "=" + key_name, null);
      */  

}
Хирал Вадодария
источник
13

Попробуйте этот код

public void deleteRow(String value)
{
SQLiteDatabase db = this.getWritableDatabase();       
db.execSQL("DELETE FROM " + TABLE_NAME+ " WHERE "+COlUMN_NAME+"='"+value+"'");
db.close();
}
Харман Кхера
источник
Как мне это вызвать, если я хочу удалить? db.deleteRow ();
Фарс
мы можем вызвать его, передав значение в качестве параметра, который вы хотите удалить. Вызовите как db.deleteRow ("имя");
Harman Khera
8

Попробуйте этот код ...

private static final String mname = "'USERNAME'";
public void deleteContact()
{
    db.delete(TABLE_CONTACTS, KEY_NAME + "=" + mname, null);
}
Гиридхаран
источник
3

если вы используете SQLiteDatabase, тогда есть метод удаления

Определение слова Delete

int delete (String table, String whereClause, String[] whereArgs)

Пример реализации

Теперь мы можем написать метод с именем delete с аргументом в качестве имени

public void delete(String value) {
    db.delete(DATABASE_TABLE, KEY_NAME + "=?", new String[]{String.valueOf(value)});
}

если вы хотите удалить все записи, просто передайте null указанному выше методу,

public void delete() {
    db.delete(DATABASE_TABLE, null, null);
}

Источник информации

Джаякришнан
источник
Если значение String прикреплено с внешним ключом, то ??
Harsh
2

Ребята, это общий метод, который вы можете использовать для всех своих таблиц. В моем случае он отлично работал.

public void deleteRowFromTable(String tableName, String columnName, String keyValue) {
    String whereClause = columnName + "=?";
    String[] whereArgs = new String[]{String.valueOf(keyValue)};
    yourDatabase.delete(tableName, whereClause, whereArgs);
}
Навид Ахмад
источник
String.ValueOf (keyValue) => не могли бы вы объяснить эту строку?
Anis
1
Нет необходимости в String.ValueOf (keyValue), потому что keyValue уже является строкой. в других случаях мы используем этот массив whereArgs для определения значения имени столбца.
Навид Ахмад
2

Чтобы удалить строки из таблицы, вам необходимо предоставить критерии выбора, которые идентифицируют строки для delete()метода. Механизм работает так же, как аргументы выбора query()метода. Он разделяет спецификацию выбора на предложение выбора (предложение where) и аргументы выбора.

    SQLiteDatabase db  = this.getWritableDatabase();
     // Define 'where' part of query.
    String selection = Contract.COLUMN_COMPANY_ID + " =?  and "
                       + Contract.CLOUMN_TYPE +" =? ";
   // Specify arguments in placeholder order.
    String[] selectionArgs = { cid,mode };
    // Issue SQL statement.
    int deletedRows = db.delete(Contract.TABLE_NAME, 
                       selection, selectionArgs);
    return deletedRows;// no.of rows deleted.

Возвращаемое значение delete()метода указывает количество строк, удаленных из базы данных.

ОЗУ
источник
Хотя этот код может ответить на вопрос, предоставление дополнительного контекста относительно того, почему и / или как этот код отвечает на вопрос, улучшает его долгосрочную ценность.
Thomas Flinkow
1

Ребята, если приведенные выше решения не работают для вас, попробуйте это также, потому что оно сработало для меня.

public boolean deleteRow(String name) 
{
    return db.delete(DATABASE_TABLE, KEY_NAME + "='" + name +"' ;", null) > 0;
}
aman003
источник
1

Прекрасно работает!

public void deleteNewMelk(String melkCode) {
    getWritableDatabase().delete(your_table, your_column +"=?", new String[]{melkCode});
}
Хади Примечание
источник
0

Попробуй это:

public void deleteEntry(long rowId) {
    database.delete(DATABASE_TABLE , KEY_ROWID 
        + " = " + rowId, null);}
Надир Титауин
источник
0
public boolean deleteRow(long l) {
    String where = "ID" + "=" + l;
    return db.delete(TABLE_COUNTRY, where, null) != 0;
}
Бабиро
источник
0

Вы можете сделать что-то вроде этого, поделившись моим рабочим фрагментом кода

Убедитесь, что запрос такой

УДАЛИТЬ ИЗ tableName WHERE KEY__NAME = 'parameterToMatch'

public void removeSingleFeedback(InputFeedback itemToDelete) {
            //Open the database
            SQLiteDatabase database = this.getWritableDatabase();

            //Execute sql query to remove from database
            //NOTE: When removing by String in SQL, value must be enclosed with ''
            database.execSQL("DELETE FROM " + TABLE_FEEDBACKS + " WHERE "
                    + KEY_CUSTMER_NAME + "= '" + itemToDelete.getStrCustName() + "'" +
                    " AND " + KEY_DESIGNATION + "= '" + itemToDelete.getStrCustDesignation() + "'" +
                    " AND " + KEY_EMAIL + "= '" + itemToDelete.getStrCustEmail() + "'" +
                    " AND " + KEY_CONTACT_NO + "= '" + itemToDelete.getStrCustContactNo() + "'" +
                    " AND " + KEY_MOBILE_NO + "= '" + itemToDelete.getStrCustMobile() + "'" +
                    " AND " + KEY_CLUSTER_NAME + "= '" + itemToDelete.getStrClusterName() + "'" +
                    " AND " + KEY_PRODUCT_NAME + "= '" + itemToDelete.getStrProductName() + "'" +
                    " AND " + KEY_INSTALL_VERSION + "= '" + itemToDelete.getStrInstalledVersion() + "'" +
                    " AND " + KEY_REQUIREMENTS + "= '" + itemToDelete.getStrRequirements() + "'" +
                    " AND " + KEY_CHALLENGES + "= '" + itemToDelete.getStrChallenges() + "'" +
                    " AND " + KEY_EXPANSION + "= '" + itemToDelete.getStrFutureExpansion() + "'" +
                    " AND " + KEY_COMMENTS + "= '" + itemToDelete.getStrComments() + "'"
            );

            //Close the database
            database.close();
        }
Хитеш Саху
источник
0

Попробуйте приведенный ниже код -

mSQLiteDatabase = getWritableDatabase();//To delete , database should be writable.
int rowDeleted = mSQLiteDatabase.delete(TABLE_NAME,id + " =?",
                    new String[] {String.valueOf(id)});
mSQLiteDatabase.close();//This is very important once database operation is done.
if(rowDeleted != 0){
    //delete success.
} else {
    //delete failed.
}
Дургеш
источник
0

Единственный способ, который сработал для меня, - это

fun removeCart(mCart: Cart) {
    val db = dbHelper.writableDatabase
    val deleteLineWithThisValue = mCart.f
    db.delete(cons.tableNames[3], Cart.KEY_f + "  LIKE  '%" + deleteLineWithThisValue + "%' ", null)
}


class Cart {
    var a: String? = null
    var b: String? = null
    var c: String? = null
    var d: String? = null
    var e: Int? = null
    var f: String? = null

companion object {
    // Labels Table Columns names
    const val rowIdKey = "_id"
    const val idKey = "id"
    const val KEY_a = "a"
    const val KEY_b = "b"
    const val KEY_c = "c"
    const val KEY_d = "d"
    const val KEY_e = "e"
    const val KEY_f = "f"
   }
}

object cons {
    val tableNames = arrayOf(
            /*0*/ "shoes",
            /*1*/ "hats",
            /*2*/ "shirt",
            /*3*/ "car"
         )
 }
Аллан Рибас
источник