Android sqlite, как проверить, существует ли запись

36

Я хочу проверить, существует ли запись или нет.

Вот что я пробовал:

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 для отображения тоста.

Что я здесь делаю неправильно?

Теги:

11 ответов

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

Я надеюсь, что это полезно для вас... Эта функция возвращает true, если запись уже существует в db. В противном случае возвращает false.

  • 4
    только коррекция, cursor.getCount ()
  • 0
    Просто добавил cursor.close() перед возвратом. Ой, это даст ошибку DatabaseLeak
Показать ещё 4 комментария
25

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

Дополнительно:
Вы можете получить сообщение об ошибке при поиске по 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;
}
  • 0
    Я предпочитаю этот ответ, потому что он учитывает тот факт, что строки могут содержать специальные символы, такие как _ или-или:. Правильный ответ !!
20

вы также можете увидеть это:

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

ИЛИ

Вы просто проверяете Cursor не null после этого, почему вы проверяете счетчик не 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 */
}
9

Необработанные запросы более уязвимы для SQL Injection. Вместо этого я предлагаю использовать метод 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;
}

Источник: здесь

  • 0
    Не знал о sqlinjection с rawQuery .. Спасибо за информацию .. :)
7

Вы можете использовать команду SELECT EXISTS и выполнить ее для cursor с помощью rawQuery, из документации

Оператор EXISTS всегда оценивает одно из целочисленных значений 0 и 1. Если выполнение инструкции SELECT, заданной как правая операнд оператора EXISTS возвращает одну или несколько строк, тогда Оператор EXISTS оценивает значение 1. Если выполнение SELECT вернется никаких строк вообще, то оператор EXISTS оценивает значение 0.

4

Я пробовал все методы, упомянутые на этой странице, но только ниже метод работал хорошо для меня.

Cursor c=db.rawQuery("SELECT * FROM user WHERE idno='"+txtID.getText()+"'", null);
if(c.moveToFirst())
{
 showMessage("Error", "Record exist");
}
else
{
 // Inserting record
}
1
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) или текущую позицию курсора.

0

Попробуйте использовать метод cursor.isNull. Пример:

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

Здесь представлено простое решение, основанное на сочетании того, что было опубликовано дипали и Пиюша Гупта:

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

из-за возможных утечек данных лучшее решение с помощью курсора:

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

1) Из API KITKAT u можно использовать ресурсы try()

try (cursor = ...some query)

2) если запрос u в отношении VARCHAR TYPE использует '...', например. COLUMN_NAME = 'string_to_search'

3) dont use moveToFirst() используется, когда вам нужно начинать итерацию с beggining

4) избегать getCount() дорого - он перебирает множество записей, чтобы их подсчитать. Он не возвращает сохраненную переменную. Может быть некоторое кэширование при втором вызове, но первый вызов не знает ответа до тех пор, пока он не будет подсчитан.

0

Код:

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню