【问题标题】:Deleting Row in SQLite in Android在 Android 中删除 SQLite 中的行
【发布时间】:2023-04-03 01:46:01
【问题描述】:

这可能是一个愚蠢的问题,但我是 SQLite 的新手,我似乎无法弄清楚这一点。我有 1 个表,其中包含 KEY_ROWIDKEY_NAMEKAY_LATITUDEKEY_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);
        }
    }
}

【问题讨论】:

  • 选择@iDroid 答案...因为它对我有用。谢谢 iDroid。

标签: android sqlite delete-row corresponding-records


【解决方案1】:

你可以这样试试:

 //---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;
}

【讨论】:

  • Vijay 的回答是正确的,因为该解决方案允许进行 SQL 注入,这是一个安全漏洞。例如:使用 name 参数的值:name = "TRUE; <any SQL command>;" => 'any SQL command' 将被执行。当然,如果没有该功能的 GUI,那也不是问题。
  • @bdevay 我的回答是关于我们使用查询完成的后台任务。所以它与UI无关。您只需要动态地提供信息,因此不需要安全性。如果您遵循 vijay 的回答并且有人进行逆向工程,那么您可能会在您正在竞争的数据库和字段中获得有关表的信息。我直接在查询中这样做,所以没有机会让它韭菜。
  • @iDroid Explorer:当然,如果没有用户输入或其他类型的外部查询操作可能性,那么安全风险不会高于其他解决方案。在下一条评论中继续...
  • ...但我不同意您评论中的逆向工程部分。您必须在某个地方以某种方式定义您的查询,这意味着逆向工程始终是一个可能的安全漏洞(即使在您的解决方案的情况下),尤其是在 Java 中,即使源代码被混淆。它只会增加更多的黑客攻击时间。另一方面,谷歌的建议是使用选择参数,请查看这篇文章:link
  • 我的意思是不给任何方法或任何变量提供静态值的概念。那应该是最大的动态。这样它比给出静态值更安全。无论如何,这取决于用户他/她想让他们的应用程序有多安全。
【解决方案2】:

这样尝试可能会得到您的解决方案

String table = "beaconTable";
String whereClause = "_id=?";
String[] whereArgs = new String[] { String.valueOf(row) };
db.delete(table, whereClause, whereArgs);

【讨论】:

    【解决方案3】:

    最好也使用 whereargs;

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

    这就像使用这个命令:

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

    并且以这种方式使用删除功能很好,因为它可以删除 sql 注入。

    【讨论】:

    • 能否请您详细说明您的答案,添加更多关于您提供的解决方案的描述?
    • 我认为值得使用whereargs
    • @Enkahi 这就像 SQLite 中的准备好的语句吗?我以前在 PHP 中使用过这种 id=? 有点语法,它看起来非常相似。
    【解决方案4】:

    在我理解你的问题之前,你想设置两个条件来选择要删除的行。为此,你需要这样做:

    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);
          */  
    
    }
    

    【讨论】:

      【解决方案5】:

      试试这个代码

      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("name");
      【解决方案6】:

      试试这个代码...

      private static final String mname = "'USERNAME'";
      public void deleteContact()
      {
          db.delete(TABLE_CONTACTS, KEY_NAME + "=" + mname, null);
      }
      

      【讨论】:

        【解决方案7】:

        这很好用:

        public boolean deleteSingleRow(String rowId) 
        {
            return db.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0;
        }
        

        您也可以参考this example

        【讨论】:

        【解决方案8】:

        如果你使用的是 SQLiteDatabase 那么有一个删除方法

        删除的定义

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

        示例实现

        现在我们可以编写一个名为delete with argument作为名称的方法

        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);
        }
        

        Source Of Information

        【讨论】:

        • 如果字符串值附加了外键那么??
        【解决方案9】:

        伙计们,这是一种可用于所有表格的通用方法,在我的情况下完美运行。

        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) => 你能解释一下这行吗?
        • 不需要String.ValueOf(keyValue),因为keyValue已经是字符串了。在其他情况下,我们使用这个 whereArgs 数组来识别列名值。
        【解决方案10】:

        要从表中删除行,您需要向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() 方法的返回值表示从数据库中删除的行数。

        【讨论】:

        • 虽然此代码可能会回答问题,但提供有关此代码为何和/或如何回答问题的额外上下文可提高其长期价值。
        【解决方案11】:

        如果上述解决方案对您不起作用,那么请尝试这个,因为它对我有用。

        public boolean deleteRow(String name) 
        {
            return db.delete(DATABASE_TABLE, KEY_NAME + "='" + name +"' ;", null) > 0;
        }
        

        【讨论】:

          【解决方案12】:

          效果很好!

          public void deleteNewMelk(String melkCode) {
              getWritableDatabase().delete(your_table, your_column +"=?", new String[]{melkCode});
          }
          

          【讨论】:

            【解决方案13】:

            试试这个:

            public void deleteEntry(long rowId) {
                database.delete(DATABASE_TABLE , KEY_ROWID 
                    + " = " + rowId, null);}
            

            【讨论】:

              【解决方案14】:
              public boolean deleteRow(long l) {
                  String where = "ID" + "=" + l;
                  return db.delete(TABLE_COUNTRY, where, null) != 0;
              }
              

              【讨论】:

                【解决方案15】:

                你可以这样做,分享我的工作代码 sn-p

                确保查询是这样的

                DELETE FROM 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();
                        }
                

                【讨论】:

                  【解决方案16】:

                  试试下面的代码-

                  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.
                  }
                  

                  【讨论】:

                    【解决方案17】:

                    对我有用的唯一方法是这个

                    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"
                             )
                     }
                    

                    【讨论】:

                      【解决方案18】:

                      但接受的答案对我不起作用。我认为字符串应该是在 SQL 中,字符串必须被引用。所以,就我而言,这对我来说与接受的答案相反:

                       database.delete(TABLE_DAILY_NOTES, WORK_ENTRY_CLUMN_NAME + "='" + workEntry+"'", null);
                      

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 2012-05-19
                        • 2019-11-07
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2021-12-29
                        相关资源
                        最近更新 更多