【问题标题】:Android sqlite how to check if a record existsAndroid sqlite如何检查记录是否存在
【发布时间】:2013-12-06 03:19:53
【问题描述】:

我想检查一条记录是否存在。

这是我尝试过的:

MainActivity.class

    public void onTextChanged(CharSequence s, int start, int before, int count) {

        System.out.println("Ontext changed " + new String(s.toString()));
        strDocumentFrom = s.toString();         

        if(s.toString().isEmpty()){

        } else {

             try{
                 strTransactionDate = dbHelper.getTransactionDateByDocumentNumber(strDocumentFrom);
                 //strTotalAmount = dbHelper.getTotalAmountByDocumentNumber(strDocumentFrom);
                 //strVan = dbHelper.getVanByDocumentNumber(strDocumentFrom);


                 //etTransactionDate.setText(strTransactionDate);
                 //etTotalAmount.setText(strTotalAmount);
                 //Log.d("Van", "" + strVan);
                 //etVan.setText(strVan);

             } catch (SQLiteException e) {
                 e.printStackTrace();
                 Toast.makeText(ReceivingStocksHeader.this, 
                         "Document number does not exist.", Toast.LENGTH_SHORT).show();
             }

        }

DBHelper.class

            // TODO DISPLAYING RECORDS TO TRANSRCVHEADER
        public String getTransactionDateByDocumentNumber(String strDocumentNumber){
            String[] columns = new String[]{KEY_TRANSACTIONDATE};

            Cursor c = myDataBase.query(TBL_INTRANS, 
                    columns, null, 
                    null, null, null, null, null);

            if(c != null){
                c.moveToFirst();
                String date = c.getString(0);
                return date;
            } else {
                Log.d("Error", "No record exists");
            }


            return null;
        }

但它并没有让它到 catch 块来显示 toast。

我在这里做错了什么?

【问题讨论】:

    标签: android sqlite


    【解决方案1】:
    public static boolean CheckIsDataAlreadyInDBorNot(String TableName,
            String dbfield, String fieldValue) {
        SQLiteDatabase sqldb = EGLifeStyleApplication.sqLiteDatabase;
        String Query = "Select * from " + TableName + " where " + dbfield + " = " + fieldValue;
        Cursor cursor = sqldb.rawQuery(Query, null);
            if(cursor.getCount() <= 0){
                cursor.close();
                return false;
            }
        cursor.close();
        return true;
    }
    

    我希望这对你有用... 如果 db 中已经存在记录,则此函数返回 true。否则返回 false。

    【讨论】:

    • 刚刚添加cursor.close(),然后返回。哦,它会给出 DatabaseLeak 错误
    • 我会在查询中添加“LIMIT 1”,因为您只需要 1 行
    • 在 Android 6.0.1 上进行测试时,上面的查询给了我 SQLiteException。当我在双引号 (") 中添加 fieldValue 时,它​​对我有用。String Query = "Select * from " + TableName + " where " + dbfield + " = \"" + fieldValue + "\";";
    • @KapilJituri 但这个功能适用于任何安卓版本。我已经检查过了。
    • @dipali 好的。请注意,原始查询更容易受到 SQL 注入的攻击。查看我的答案以了解首选方式。
    【解决方案2】:

    这些都是很好的答案,但是很多人忘记了关闭游标和数据库。如果您不关闭游标或数据库,您可能会遇到内存泄漏。

    另外:
    当使用包含非字母/数字字符的String 进行搜索时,您可能会遇到错误。例如:“1a5f9ea3-ec4b-406b-a567-e6927640db40”。这些破折号 (-) 将导致 unrecognized token 错误。您可以通过将字符串放入数组来克服这个问题。所以养成这样查询的习惯:

    public boolean hasObject(String id) {
        SQLiteDatabase db = getWritableDatabase();
        String selectString = "SELECT * FROM " + _TABLE + " WHERE " + _ID + " =?";
    
        // Add the String you are searching by here. 
        // Put it in an array to avoid an unrecognized token error 
        Cursor cursor = db.rawQuery(selectString, new String[] {id}); 
    
        boolean hasObject = false;
        if(cursor.moveToFirst()){
            hasObject = true;
    
            //region if you had multiple records to check for, use this region. 
    
            int count = 0;
            while(cursor.moveToNext()){
              count++;
            }
            //here, count is records found
            Log.d(TAG, String.format("%d records found", count));
    
            //endregion
    
        } 
    
        cursor.close();          // Dont forget to close your cursor
        db.close();              //AND your Database!
        return hasObject;
    }
    

    【讨论】:

    • 我更喜欢这个答案,因为它考虑到字符串可能包含特殊字符,如 _ or-or :.正确答案!!
    • 确实,我是从 firebase 获取数据的,尽管该列存在,但它已经 - 并且遇到了一个奇怪的“没有这样的列”问题......
    【解决方案3】:

    你也可以看到这个:

    if (cursor.moveToFirst()) {
    // record exists
    } else {
    // record not found
    }
    

    你只是检查 Cursor not null 之后为什么你检查 count 不是 0。

    所以,你试试这个...

    DBHelper.getReadableDatabase();
    
    Cursor mCursor = db.rawQuery("SELECT * FROM " + DATABASE_TABLE + " WHERE    yourKey=? AND yourKey1=?", new String[]{keyValue,keyvalue1});
    
    if (mCursor != null)
    {
                return true;
    /* record exist */
     }
    else
    {
            return false;
    /* record not exist */
    }
    

    【讨论】:

      【解决方案4】:

      原始查询更容易受到 SQL 注入的攻击。我会建议改用query() 方法。

      public boolean Exists(String searchItem) {
      
          String[] columns = { COLUMN_NAME };
          String selection = COLUMN_NAME + " =?";
          String[] selectionArgs = { searchItem };
          String limit = "1";
      
          Cursor cursor = db.query(TABLE_NAME, columns, selection, selectionArgs, null, null, null, limit);
          boolean exists = (cursor.getCount() > 0);
          cursor.close();
          return exists;
      }
      

      来源:here

      【讨论】:

      • 不知道 sqlinjectionrawQuery.. 感谢您的信息.. :)
      【解决方案5】:

      您可以使用SELECT EXISTS 命令并使用rawQuerycursor 执行它, 来自文档

      EXISTS 运算符的计算结果始终为整数值之一 0 和 1. 如果执行指定为右手的 SELECT 语句 EXISTS 运算符的操作数将返回一行或多行,然后 EXISTS 运算符的计算结果为 1。如果执行 SELECT 将返回 根本没有行,那么 EXISTS 运算符的计算结果为 0。

      【讨论】:

        【解决方案6】:

        SELECT EXISTSLIMIT 1 更快。​​

        查询示例SELECT EXISTS (SELECT * FROM table_name WHERE column='value' LIMIT 1);

        代码示例:

        public boolean columnExists(String value) {
            String sql = "SELECT EXISTS (SELECT * FROM table_name WHERE column='"+value+"' LIMIT 1)";
            Cursor cursor = database.rawQuery(sql, null);
            cursor.moveToFirst();
        
            // cursor.getInt(0) is 1 if column with value exists
            if (cursor.getInt(0) == 1) { 
                cursor.close();
                return true;
            } else {
                cursor.close();
                return false;
            }
        }
        

        【讨论】:

        • 我认为这个解决方案非常酷,尤其是使用 LIMIT 1。但是如果我做到了——“SELECT EXISTS (SELECT 1 FROM .....”你认为这可能会更快吗? ?
        • @YoApps 如果你问我的话,不多。看到这个答案dba.stackexchange.com/questions/159413/…
        【解决方案7】:

        我已经尝试了本页中提到的所有方法,但只有以下方法对我有效。

        Cursor c=db.rawQuery("SELECT * FROM user WHERE idno='"+txtID.getText()+"'", null);
        if(c.moveToFirst())
        {
         showMessage("Error", "Record exist");
        }
        else
        {
         // Inserting record
        }
        

        【讨论】:

          【解决方案8】:

          投票最多的答案没有提到的一件事是,如果搜索值是这样的文本值,则需要在搜索值周围加上单引号“like this”:

          public boolean checkIfMyTitleExists(String title) {
              String Query = "Select * from " + TABLE_NAME + " where " + COL1 + " = " + "'" + title + "'";
              Cursor cursor = database.rawQuery(Query, null);
              if(cursor.getCount() <= 0){
                  cursor.close();
                  return false;
              }
              cursor.close();
          
              return true;
          }
          

          否则,您将收到“SQL(查询)错误或缺少数据库”错误,就像我在 title 字段周围没有单引号时所做的那样。

          如果是数值,则不需要单引号。

          参考这个SQL post for more details

          【讨论】:

            【解决方案9】:
            SQLiteDatabase sqldb = MyProvider.db;
            String Query = "Select * from " + TABLE_NAME ;
            Cursor cursor = sqldb.rawQuery(Query, null);
            cursor.moveToLast(); //if you not place this cursor.getCount() always give same integer (1) or current position of cursor.
            
            if(cursor.getCount()<=0){
                Log.v("tag","if 1 "+cursor.getCount());
                return false;
            }
            Log.v("tag","2 else  "+cursor.getCount());
            
            return true;
            

            如果你不使用cursor.moveToLast();

            cursor.getCount() 总是给出相同的整数 (1) 或光标的当前位置。

            【讨论】:

              【解决方案10】:

              代码:

              private String[] allPushColumns = { MySQLiteHelper.COLUMN_PUSH_ID,
                      MySQLiteHelper.COLUMN_PUSH_TITLE, MySQLiteHelper.COLUMN_PUSH_CONTENT, MySQLiteHelper.COLUMN_PUSH_TIME,
                      MySQLiteHelper.COLUMN_PUSH_TYPE, MySQLiteHelper.COLUMN_PUSH_MSG_ID}; 
              
              public boolean checkUniqueId(String msg_id){
              
                  Cursor cursor = database.query(MySQLiteHelper.TABLE_PUSH,
                          allPushColumns, MySQLiteHelper.COLUMN_PUSH_MSG_ID + "=?", new String [] { msg_id }, null, null, MySQLiteHelper.COLUMN_PUSH_ID +" DESC");
              
                  if(cursor.getCount() <= 0){
                      return false;
                  }
                  return true;
              }
              

              【讨论】:

                【解决方案11】:

                以下是基于 dipali 和 Piyush Gupta 发布的内容的简单解决方案:

                  public boolean dbHasData(String searchTable, String searchColumn, String searchKey) {
                    String query = "Select * from " + searchTable + " where " + searchColumn + " = ?";
                    return getReadableDatabase().rawQuery(query, new String[]{searchKey}).moveToFirst();
                  }
                

                【讨论】:

                  【解决方案12】:

                  由于可能的数据泄漏,最好通过游标解决:

                   Cursor cursor = null;
                      try {
                            cursor =  .... some query (raw or not your choice)
                            return cursor.moveToNext();
                      } finally {
                          if (cursor != null) {
                              cursor.close();
                          }
                      }
                  

                  1) 从 API KITKAT 你可以使用资源 try()

                  try (cursor = ...some query)
                  

                  2) 如果你查询 VARCHAR TYPE 使用 '...' 例如。 COLUMN_NAME='string_to_search'

                  3) 当你需要从头开始迭代时,不要使用 moveToFirst()

                  4) 避免 getCount() 代价高昂——它会遍历许多记录来计算它们。它不返回存储的变量。第二次调用可能会有一些缓存,但第一次调用直到被计数才知道答案。

                  【讨论】:

                    【解决方案13】:

                    尝试使用 cursor.isNull 方法。 示例:

                    song.isFavorite = cursor.isNull(cursor.getColumnIndex("favorite"));
                    

                    【讨论】:

                      【解决方案14】:

                      你可以这样使用:

                      String Query = "Select * from " + TABLE_NAME + " where " + Cust_id + " = " + cust_no;
                      
                      Cursor cursorr = db.rawQuery(Query, null);
                      if(cursor.getCount() <= 0){
                      cursorr.close();
                      }
                      cursor.close();
                      

                      【讨论】:

                        【解决方案15】:
                        private boolean checkDataExistOrNot(String columnName, String value) {
                            SQLiteDatabase sqLiteDatabase = getReadableDatabase();
                            String query = "SELECT * FROM" + TABLE_NAME + " WHERE " + columnName + " = " + value;
                            Cursor cursor = sqLiteDatabase.rawQuery(query, null);
                            if (cursor.getCount() <= 0) {
                                cursor.close();
                                return false;  // return false if value not exists in database
                            }
                            cursor.close();
                            return true;  // return true if value exists in database
                        }
                        

                        【讨论】:

                          猜你喜欢
                          • 1970-01-01
                          • 2015-06-12
                          • 1970-01-01
                          • 1970-01-01
                          • 2012-11-21
                          • 2019-10-13
                          • 2019-04-07
                          • 1970-01-01
                          • 1970-01-01
                          相关资源
                          最近更新 更多