How to do a SQLiteDatabase contains search in Android - java

As far as I'm aware of the character ? is used as a placeholder and it will be replaced with the value that you pass in the whereArgs String array.
This is my code for the query:
String whereClause = null;
String[] whereArgs = null;
if (search != "") {
whereClause = InventoryEntry.COLUMN_INVENTORY_ITEM_NAME +
" CONTAINS(" + InventoryEntry.COLUMN_INVENTORY_ITEM_NAME + ",?)";
whereArgs = new String[]{search};
}
Cursor cursor = db.query(InventoryEntry.TABLE_NAME,
null,
whereClause,
whereArgs,
null,
null,
orderBy
);
When I go to execute the query I get the following error:
android.database.sqlite.SQLiteException: near "CONTAINS": syntax error (code 1): , while compiling: SELECT * FROM items WHERE itemName CONTAINS(itemName,?) ORDER BY date ASC
What do I need to change so that my query will be in the form of:
SELECT * FROM items WHERE itemName CONTAINS(itemName,`search`);
Also, is it proper practice to use CONTAINS over LIKE?
Thank you!

SQLite does not have a CONTAINS keyword.
You could do something LIKE this:
whereClause = InventoryEntry.COLUMN_INVENTORY_ITEM_NAME +
" LIKE " + InventoryEntry.COLUMN_INVENTORY_ITEM_NAME +
" OR " + InventoryEntry.COLUMN_INVENTORY_ITEM_NAME +
" LIKE ?";
whereArgs = new String[]{search};
Also, do not compare strings with the != operator, use the equals() method::
if (!"".equals(search)) {
// ...
}
Or check the length of the String:
if (search != null && search.length() > 0) {
// ...
}
The != operator checks for reference equality when comparing objects.

Related

Modifying SQLite Search Parameters to Return Full String From One Word Instead of Specific Order

I am having trouble with altering the search parameters within SQLite, currently, the search functions that I have for searching film titles and genres can only return the specific result, e.g., Action will only bring back Action films and not Action, Adventure films.
I have had a friend manage to have it work within the SQLite Studio itself, but using this method has been unsuccessful. He suggested using the following ORDER BY, however, it still gives the same results.
Cursor c = sqdb.rawQuery("SELECT * FROM filmography WHERE genre LIKE '%" + searchGenre + "' ORDER BY LENGTH(genre) ASC",
null);
I am at a loss now as I cannot seem to come across or figure out the answer. How would I go about changing the SQL so that if you were to search say "Action" in the genre search, it would bring back all results so eg., "Film 1 = Action, Film 2 = Action, Adventure, Film 3 = Action, Crime" and so on?
Example of genre data: "Capone, Biography, Crime, Drama, Fonse, 2020, 4.7/10
Black Hawk Down, Drama, History, War, Twombly, 2001, 7.7/10
Venom, Action, Adventure, Sci-Fi, Eddie Brock / Venom, 2018, 6.7/10
public String searchByTitleInFilmography(SQLiteDatabase sqdb, String searchfilmTitle)
{
String result = "";
Cursor c = sqdb.rawQuery("SELECT * FROM filmography WHERE filmTitle = '" + searchfilmTitle + "'",
null);
if (c != null)
{
if (c.moveToFirst())
{
do
{
String id = c.getString(0);
result = result + id + ": ";
String filmtitle = c.getString(1);
result = result + "Title: " + filmtitle + ". ";
String genre = c.getString(2);
result = result + "Genre(s): " + genre + ". ";
String role = c.getString(3);
result = result + "Role: " + role + ". ";
String year = c.getString(4);
result = result + "Released: " + year + ". ";
String imdbrating = c.getString(5);
result = result + "Rating: " + imdbrating + "\n" + "\n";
Log.w("FILM_TITLE_GENRE", "ID - " + id +":" + " Genre(s) = " + genre);
} while (c.moveToNext());
}
else
{
result = "No Films Found With The Title = " + searchfilmTitle;
}
}
c.close();
return result;
} // public String serachByTitleInFilmography(SQLiteDatabase sqdb, String searchTitle)
If the column genre contains values like a comma separated list of genres, then you should change the operand of the operator LIKE like this:
String sql = "SELECT * FROM filmography WHERE ',' || REPLACE(genre, ', ', ',') || ',' LIKE '%,' || ? || ',%'"
Cursor c = sqdb.rawQuery(sql, new String[] {searchGenre});
REPLACE() removes all spaces after each comma and each value of genre becomes like: ',Action,Crime,Drama,'.
When you pass 'Action' as the parameter for the ? placeholder then the sql statement becomes:
SELECT * FROM filmography WHERE ',Action,Crime,Drama,' LIKE '%,Action,%'
which is what you want: all the rows that contain 'Action' anywhere in the column genre.

How to control where id is equal to unknown number of variable sql query?

I am looking for something like that:
String ID = ContactsContract.Contacts._ID;
ContentResolver cR = context.getContentResolver();
Cursor cursor = cR.query(mUri, null, ID + " =?", mStringArray, null);
mStringArray is not obvious, and the user will assign its elements. So we don't know what is the length of the array and what elements mStringArray has. I want to query for every values of mStringArray. In that case, i am getting an error which is "IllegalArgumentException: Cannot bind argument at index 2(or 3,4,...) because the index is out of range. The statement has 1 parameters".
I hope i am clear.
Instead of = you should use the operator IN and construct the statement with as many ? placeholders as the items of the array mStringArray:
String ID = ContactsContract.Contacts._ID;
ContentResolver cR = context.getContentResolver();
StringBuilder sb = new StringBuilder();
for (String s : mStringArray ) {
sb.append("?,");
}
String sqlIn = null;
if (sb.length() > 0) {
sb.deleteCharAt(sb.length() - 1);
sqlIn = ID + " IN (" + sb.toString() + ")";
}
Cursor cursor = cR.query(mUri, null, sqlIn, mStringArray, null);

Android - sqlite in clause using string values from arraylist?

public void DBSearchCategory(String tableName) {
// 1st way
String inClause = s1.ListViewCategory.toString();
inClause = inClause.replace("[", "(");
inClause = inClause.replace("]", ")");
// Cursor cursor = database.rawQuery("SELECT CATEGORY FROM " + tableName
// + " WHERE CATEGORY NOT IN " + inClause
// + " ORDER BY RANDOM() LIMIT 1 ", null);
// 2nd way
try {
StringBuilder sb = new StringBuilder("");
for (String param : s1.ListViewCategory) {
sb.append(",").append('"').append(param).append('"');
}
params = sb.toString().substring(1);
Log.v("Tag", "params value is " + params);
} catch (StringIndexOutOfBoundsException e) {
}
Cursor cursor = database.rawQuery("SELECT CATEGORY FROM " + tableName
+ " WHERE CATEGORY NOT IN (?) "
+ " ORDER BY RANDOM() LIMIT 1 ", new String[]{params});
while (cursor.moveToNext()) {
category = cursor.getString(cursor.getColumnIndex("CATEGORY"));
s1.keyCategory = category;
}
cursor.close();
}
s1.ListViewCategory is a String type ArrayList in Singleton class s1, and it has values of categories: "game","country","city","subway","actor","pet" // In Database there are total 33 categories, and I want to exclude these 6 categories that are in s1.ListViewCategory
In rawQuery, I want to exclude categories that are in s1.ListViewCategory, so I tried 2 ways of cursor refering to these 2 stackoverflow questions:
Android - sqlite in clause using string values from array?
///Android - sqlite in clause using values from array
I used WHERE and NOT IN statement to exclude these 6 categories
When I tried 2nd way cursor, I got no error. However, the Sql query did not work. It had to exclude categories that are in String[params], but it did not work. So I used log to see what param is and I got this
2020-01-09 09:16:47.233 8978-8978/com.kj.word V/Tag: params value is
"game","country","city","subway","actor","pet"
When I tried 1st Cursor Category, I got error logcat:
Error Code : 1 (SQLITE_ERROR)
Caused By : SQL(query) error or missing database.
(no such column: game (code 1): , while compiling: SELECT CATEGORY FROM KeyWordDB WHERE CATEGORY
NOT IN (game, country, city, subway, actor, pet) ORDER BY RANDOM() LIMIT 1)
#################################################################
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:1008)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:573)
at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:59)
at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37)
at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:44)
at android.database.sqlite.SQLite
I confirmed that there is a database, so I guess it is probably sql query problem ...
So my question is How can I fix 1st or 2nd cursor to exclude categories that are in s1.ListViewCateogry?
I've searched real hard, but I wasn't able to find answer... Ill be real grateful, if someone answers this question
Change the double quotes with single quotes inside the loop that constructs the comma delimited list:
for (String param : s1.ListViewCategory) {
sb.append(",").append("'").append(param).append("'");
}
params = sb.toString().substring(1);
This code constructs a list like:
'game', 'country', 'city', 'subway', 'actor', 'pet'
If you use it as a parameter in the rawQuery() method then this list will be treated as a string literal and not a list of values.
So do this instead:
String sql = "SELECT CATEGORY FROM " + tableName
+ " WHERE CATEGORY NOT IN (?) "
+ " ORDER BY RANDOM() LIMIT 1 ";
sql = sql.replace("?", params);
Cursor cursor = database.rawQuery(sql, null);
Note that this method is prone to sql injection.
Another way is to create a list of ? placeholders instead of 1 placeholder and pass the list of values as an array of strings like this:
for (String param : s1.ListViewCategory) {
sb.append(",?");
}
String[] array = ListViewCategory.toArray(new String[s1.ListViewCategory.size()]);
params = sb.toString().substring(1);
String sql = "SELECT CATEGORY FROM " + tableName
+ " WHERE CATEGORY NOT IN (#) "
+ " ORDER BY RANDOM() LIMIT 1 ";
sql = sql.replace("#", params);
Cursor cursor = database.rawQuery(sql, array);

error occur when try to SELECT in sqlite android

so i recently learn to write a code in android using sqlite and i try to select data from sqlite but this error occur
ive tried some suggestion from the internet and read my book but i didnt solve my problem
public Penyakit getPenyakit1(String namaGejal){
SQLiteDatabase db = this.getReadableDatabase();
String query = "SELECT idPen FROM " + TABLE_CONTACTS + " WHERE " +
namapen + " =\"" + namaGejal + "\"";
Cursor cursor = db.rawQuery(query,null);
Penyakit penyakit = new Penyakit();
if(cursor.moveToFirst()){
cursor.moveToFirst();
penyakit.set_nomber(Integer.parseInt(cursor.getColumnName(0)));
penyakit.set_namaPen(cursor.getColumnName(1));
penyakit.set_idPenyakit(Integer.parseInt(cursor.getColumnName(2)));
penyakit.set_namGej(cursor.getColumnName(3));
penyakit.set_idGejala(Integer.parseInt(cursor.getColumnName(4)));
cursor.close();
} else {
penyakit=null;
}
return penyakit;
}
this is logcat
Process: com.example.lordbramasta.pakar, PID: 18914
java.lang.NumberFormatException: For input string: "idPen"
at java.lang.Integer.parseInt(Integer.java:615)
at java.lang.Integer.parseInt(Integer.java:650)
at com.example.lordbramasta.pakar.DBAdapter.getPenyakit1(DBAdapter.java:79)
i expected the value of idPen get selected , thank you
Your problem is this line:
penyakit.set_nomber(Integer.parseInt(cursor.getColumnName(0)));
cursor.getColumnName(0) returns idPen as this is the name of the only column returned by your query:
SELECT idPen FROM ....
and your code is trying to cast the string "idPen" to an integer.
So getColumnName() returns the name of the column at a specified index and not the value of the column.
You should do
penyakit.set_nomber(Integer.parseInt(cursor.getString(0)));
or if the data type of the column idPen is INTEGER then:
penyakit.set_nomber(cursor.getInt(0));
Also don't try to get any other columns because your query returns only 1.
Note: remove that cursor.moveToFirst(); inside the if block because it is already executed.
Probably you need to use a ' instead of ". So, change the query to the following:
String query = "SELECT idPen FROM " + TABLE_CONTACTS + " WHERE " +
namapen + " =\'" + namaGejal + "\'";
I'm suggesting you to use SQLiteDatabase.query() instead rawQuery like this:
// Define a projection that specifies which columns from the database
// you will actually use after this query.
String[] projection = {
"idPen"
};
// Filter results WHERE "namapen" = 'namaGejal'
String selection = "namapen" + " = ?";
String[] selectionArgs = { namaGejal };
// How you want the results sorted in the resulting Cursor
String sortOrder = null; // null for default order
Cursor cursor = db.query(
TABLE_CONTACTS, // The table to query
projection, // The array of columns to return (pass null to get all)
selection, // The columns for the WHERE clause
selectionArgs, // The values for the WHERE clause
null, // don't group the rows
null, // don't filter by row groups
sortOrder // The sort order
);
// do something with the cursor
Please take a look Read information from a database
If you want to get all columns data from your TABLE_CONTACTS use SELECT * FROM

Android / Java: How to get last row value in sqlite?

Hello I am using a sqlite database in my android application, and I have question:
I am trying to get the last value text(thats the collumn) from the last row from the table TABLE_XYZ... but it does not work.. i am using the following code...what am I doing wrong?
another question is, how can I return two values instead of only one, when I want to get several values from the last row like column text and message?
private static final String KEY_MESSAGE = "message";
private static final String KEY_TEXT = "text";
...
String selectQuery= "SELECT * FROM " + TABLE_XYZ+" ORDER BY column DESC LIMIT 1";
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
cursor.close();
return cursor.getString( cursor.getColumnIndex(KEY_TEXT) );
EDIT:
i hade some errors in my Query,, i fixed it, but still have errors:
String selectQuery= "SELECT * FROM " + TABLE_XYZ + " ORDER BY " + KEY_TEXT+ " DESC LIMIT 1";
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
String str = cursor.getString( cursor.getColumnIndex(KEY_TEXT );
cursor.close();
return str;
while debugging I can see that cursor does have the right values inside... but when i try to get the column value with this command "cursor.getString( cursor.getColumnIndex(KEY_TEXT );"... it does not work...
you are closing cursor before getting it's value
try this :
String selectQuery= "SELECT * FROM " + TABLE_XYZ+" ORDER BY column DESC LIMIT 1";
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
String str = "";
if(cursor.moveToFirst())
str = cursor.getString( cursor.getColumnIndex(KEY_TEXT) );
cursor.close();
return str;
From the android documentation: http://developer.android.com/reference/android/database/Cursor.html
abstract void close()
Closes the Cursor, releasing all of its resources and making it completely invalid.
You are closing the cursor before returningthe string.
Like #whatever5599451 said you should not close the cursor before you get value. Also try a query like this:
String selectQuery = "SELECT column FROM " + TABLE_XYZ +
" ORDER BY column DESC LIMIT 1";
You can specify the columns also specify to return only 1 row.
This will bring back only the column you are ordering by you can also specify more columns example:
String selectQuery = "SELECT column, column2, column3 FROM " + TABLE_XYZ +
" ORDER BY column DESC LIMIT 1";
* means select all columns
to get the last column, use the name of the column instead of " * " (* means all, all the fields)
#Steve: do this:
String selectQuery= "SELECT " + KEY_TEXT + " FROM " + TABLE_XYZ + " ORDER BY " + KEY_TEXT+ " DESC LIMIT 1";
then you get just one String with the last record containing just the right column

Categories