简体   繁体   中英

Check if some string is in SQLite database

I have some trouble with a SQLite database with 1 table and 2 columns, column_id and word . I extended SQLiteAssetHelper as MyDatabase and made a constructor:

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

I need to check whether some string is in the database (in column word ). I tried to modify the code from answer provided by Benjamin and dipali , but I used SQLiteAssetHelper and I can't get it to work. The method that I have in mind receives the string to search for as a parameter and returns a boolean if string is in the database.

public boolean someMethod(String s)

In addition, I tried to put the check on a background thread with AsyncTask because I have 60 strings to check.

TABLE_NAME and COLUMN_WORD should be self-explanatory.

public boolean someMethod(String s) {
    SQLiteDatabase db = getReadableDatabase();
    String[] columns = new String[] {COLUMN_WORD};
    String where = COLUMN_WORD + " = ?";
    String[] whereArgs = new String[] {s};

    // select column_word from table where column_word = 's' limit 1;
    Cursor cursor = db.query(TABLE_NAME, columns, where, whereArgs, null, null, null, "1");
    if (cursor.moveToFirst()) {
        return true; // a row was found
    }
    return false; // no row was found
}

You can do this in the background, but I don't think for a query like this it's even necessary.

EDIT

There are some improvements that should be made to the above for the sake of correctness. For one thing, the Cursor should be closed since it is no longer being used. A try-finally block will ensure this:

Cursor cursor = db.query(...);
try {
    return cursor.moveToFirst();
} finally {
    cursor.close();
}

However, this method doesn't need to obtain a whole `Cursor. You can write it as follows and it should be more performant:

public boolean someMethod(String s) {
    SQLiteDatabase db = getReadableDatabase();
    String sql = "select count(*) from " + TABLE_NAME + " where "
            + COLUMN_WORD + " = " + DatabaseUtils.sqlEscapeString(s);
    SQLiteStatement statement = db.compileStatement(sql);

    try {
        return statement.simpleQueryForLong() > 0;
    } finally {
        statement.close();
    }
}

You could add a catch block and return false if you think it's possible (and valid) to encounter certain exceptions like SQLiteDoneException . Also note the use of DatabaseUtils.sqlEscapeString() because s is now concatenated directly into the query string and thus we should be wary of SQL injection. (If you can guarantee that s is not malicious by the time it gets passed in as the method argument, then you could theoretically skip this, but I wouldn't.)

because of possible data leaks best solution via cursor:

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

1) From API KITKAT u can use resources try()

try (cursor = ...some query)

2) if u query against VARCHAR TYPE use '...' eg. COLUMN_NAME='string_to_search'

3) dont use moveToFirst() is used when you need to start iterating from beggining

4) avoid getCount() is expensive - it iterates over many records to count them. It doesn't return a stored variable. There may be some caching on a second call, but the first call doesn't know the answer until it is counted.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM