SQLite get ids and names WHERE name LIKE - android

id| name |...
--------------
1 |Emmi blaa|..
2 |Emmi haa |..
3 |Emmi naa |..
I have SQLite database with table named contacts that contain id, name and other information. I'm trying to get name and id with name variable that I give in EditText.
String query = "SELECT name, id FROM contacts WHERE name LIKE \"%" + name + "%\"";
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursorC = db.rawQuery(query, null);
while (cursorC.moveToNext()) {
System.out.println(cursorC.getString(0));
}
With the code above, I'm only able to get the names, but not the id so I tried GROUP_CONCAT
String query = "SELECT id, GROUP_CONCAT(name) FROM contacts WHERE name LIKE \"%" + name + "%\" GROUP BY id";
Now I get the ids only. How would I get both Id and name with name variable being "mm" for example?

I believe that your issue is not that the first query was not getting the id, rather that you weren't retrieving the id column from the cursor.
The following would work :-
String query = "SELECT name, id FROM contacts WHERE name LIKE \"%" + name + "%\"";
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursorC = db.rawQuery(query, null);
while (cursorC.moveToNext()) {
System.out.println(cursorC.getString(0) + " : " + cursorC.getString(1));
}
However, ideally you should use the Cursor getLong method for retrieving id's as the id can be as large as a 64bit signed integer. So System.out.println(cursorC.getString(0) + " : " + String.valueOf(cursorC.getLong(1))); would be better.
Additionally an improvement would be to use the Cursor's getColumnIndex(the_column_name) method. This is more flexible as the index of the column is determined according to the column's name. As such System.out.println(cursorC.getString(cursorC.getColumnIndex("name")) + " : " + String.valueOf(cursorC.getLong(cursorC.getColumnIndex("id")))); would be recommended (it is also recommended that table and column names are defined as constants and then that those constants are used rather than hard coding the column/table names).
e.g. if the query were changed to SELECT id, name FROM contacts WHERE name LIKE \"%" + name + "%\"" then using hard-coded offsets 0 and 1 would transpose the results. However the results would be unchanged if using getColumnIndex.
If you wanted to use the 2nd query String query = "SELECT id, GROUP_CONCAT(name) FROM contacts WHERE name LIKE \"%" + name + "%\" GROUP BY id"; then note that the column names in the Cursor are id and GROUP_CONCAT(name), generally an alias would be given to the name using the AS keyword. e.g. String query = "SELECT id, GROUP_CONCAT(name) AS all_names FROM contacts WHERE name LIKE \"%" + name + "%\" GROUP BY id"; The column name in the resultant cursor would then be all_names.

Everything is ok with your first query. You are getting only name because you are getting only first column of the result: System.out.println(cursorC.getString(0));
To get other columns use similar methods cursor.getString() or cursor.getInteger() with 1 as parameter. Or even cursor.getInt(cursor.getColumnIndex("id"))
From the docs:
For each row, you can read a column's value by calling one of the Cursor get methods, such as getString() or getLong(). For each of the get methods, you must pass the index position of the column you desire, which you can get by calling getColumnIndex() or getColumnIndexOrThrow().

Related

Android SQLITE : Get Id value based on column value

I am building my first android app where I am trying to sync mysql data to sqlite in android. I have two tables in mysql and both gets synced properly into android sqlite. The first table is as follows:
id ProjectName
1 RA_Tesco
2 RA_Coors
3 RA_JWNT
The second table is as follows:
id pid Outlet Add1
1 1 Tesco XYZ
2 1 Tesco ABC
3 2 Coors NBC
The PID in second table references to id of first table. How can I subset the second table based on PID value derived from id of first table. I know it is pretty straight forward in php or mysql or even in Python or R. However, fetching the id based on string and referencing the same in the second table seems quite tricky in Android. My codes so far:
sqLiteDatabase = sqLiteHelper.getWritableDatabase();
clickedId = getIntent().getExtras().get("clickedId").toString();
When I toast clickedId, I get the correct string, for example, RA_Tesco.
cursor = sqLiteDatabase.rawQuery("SELECT * FROM "+SQLiteHelper.TABLE_NAME1+" where pid = 1"+"", null);
The above code also renders the correct set of records from the sqlite table. I am struggling with integrating them both. I tried the following:
String pid;
sqLiteDatabase = sqLiteHelper.getWritableDatabase();
clickedId = getIntent().getExtras().get("clickedId").toString();
pid = sqLiteDatabase.rawQuery( "select id from "+sqLiteHelper.TABLE_NAME+" where projectName = "+clickedId+"", null );
I am getting incompatible types error.
This is what worked for me:
clickedId = getIntent().getExtras().get("clickedId").toString();
cursor = sqLiteDatabase.rawQuery("SELECT * FROM "+SQLiteHelper.TABLE_NAME1+" where pid = (select id from "+SQLiteHelper.TABLE_NAME+ " where ProjectName = '"+clickedId+"'"+")", null);
I just followed the same MySQL principle of nesting queries. The above code roughly reads as follows:
select * from table2 where pid = (select id from table1 where projectname="xyz");
1) Try put your query to single quote
2) rawQuery returns Cursor, not String
So,
Cursor pidCursor = sqLiteDatabase.rawQuery( "select id from "+sqLiteHelper.TABLE_NAME+" where projectName = '"+clickedId+"'", null );
If you want to get the corresponding rows from the 2nd table when you pass as an argumnent the value of a ProjectName (I guess this is clickedId although its name is id?), create a statement like this:
String sql =
"select t2.* from " + SQLiteHelper.TABLE_NAME1 +
" t2 inner join " + SQLiteHelper.TABLE_NAME +
" t1 on t1.id = t2.pid where t1.ProjectName = ?";
This joins the 2 tables and returns all the columns of the 2nd table.
The execute rawQuery() by passing clickedId as a parameter, which is the proper way to avoid sql injection:
Cursor cursor = sqLiteDatabase.rawQuery(sql, new String[] {clickedId});

Check if column string in database is a substring of a query in sqlite

the current Sqlite syntax can check if a query is a substring of a column string.
and I can do a hack to add a % behind the ? described in https://stackoverflow.com/a/5752671/908821
final String whereClause = DbHelper.COLUMN_URL + " LIKE ? " ;
is there a syntax where i can do the opposite? I want to check if the column string is a substring of a query.
The following code does not seem to work.
final String whereClause = "? LIKE " + DbHelper.COLUMN_URL ;
The following are the rest of my codes:
String[] whereArg = {url};
ContentValues values = new ContentValues();
values.put(DbHelper.COLUMN_LAST_URL, lastUrl);
database.updateWithOnConflict(DbHelper.TABLE_BOOKMARK,
values,
whereClause,
whereArg,
SQLiteDatabase.CONFLICT_IGNORE);
I am trying to update "LastUrl" column if the base url is a subString of a query.
some examples that i like to catch
Base Url (in database) Query
-----------------------------------------------------------------
http://example.com/path http://example.com/path/path2
http://example.com/path?id=0 http://example.com/path?id=0&x=xx
The LIKE operator checks whether the value on the left matches the pattern on the right. So just put the value on the left, and the pattern on the right.
If the pattern needs a % that is not in the database, you have to append it:
SELECT ... WHERE ? LIKE LastUrl || '%' ...

SQLite: FTS search user-input string in my app

I am trying to search on search database for user-input string. I would like to show any record that matches one or more input words.
I right now have following code/Query:
String sqlStr = "SELECT ID as _id, * FROM Had_Table
WHERE Collection_ID = " + CID + whereClause + "
AND ID IN (SELECT rowid FROM Had_Virtual_Table
WHERE Had_Virtual_Table MATCH ?
)";
String[] qStr = {query};
Cursor sHadCursor = sHadlistDB.rawQuery(sqlStr, qStr);
This returns results for a string, say, "Fat cat" only if they both exist in a record. I would like to get record even if it has only one of those words.
Also, I want records not be repeated twice(or more) if both words(fact cat) are found in a particular record.
Can anyone suggest anything?
Thank you

New Column added to a table doesnt show up in query

I am adding a new column to an existing table and adding a new entry to the table with valid data present only in new column (other column being 0 by default)
Adding Column :
final String DB_ADD_COLUMN_STATEMENT_TABLE_SHOP_NAME =
"ALTER TABLE "+ shopName + " ADD COLUMN "+ "D" + time + " FLOAT";
try {
mDB.beginTransaction();
//SQLiteStatement statement = mDB.compileStatement(DB_ADD_COLUMN_STATEMENT_TABLE_SHOP_NAME);
//statement.execute();
mDB.execSQL(DB_ADD_COLUMN_STATEMENT_TABLE_SHOP_NAME);
mDB.setTransactionSuccessful();
}
catch (Exception e) {
Log.d(LOG_TAG,"addItemSample : Exception while adding column to table!!");
}
finally {
mDB.endTransaction();
}
Adding a new entry to the table with data only in this column succeeds.
But when I query the table , this new column doesn't show up in the cursor.
Though the adding column and querying happen in different threads, they are serialized from the way they are being called from my code (ie first column is added and then db is queried) and also the I am using a single connection to db.
I wondering what might be reason for this?
PS:When db query is performed immediately after inserting the column , it shows up.
depends on your query statement.
is it like
String query="select id, column1, column 2 from "+shopName+" where yourcondition";
?
may be you have to add column?
String query="select id, column1, column2, D192200 from "+shopName+"";
or you may query all columns
String query="select * from "+shopName+"";
The issue could be that you are adding a column that expects NOT NULL values
Try something like this:
ALTER TABLE "+ shopName + " ADD COLUMN "+ "D" + time + " FLOAT" default 0 NOT NULL;
Use which ever default value you need and update the values as needed.

Conditional update within ContentProvider

I have a database with table Cities, which has two columns id and is_default declared as integer. I would like to update all cities the way that only one city has value 1 set in is_default column at the same time. My database is wrapped by ContentProvider so I want to use ContentResolver for this. Here's my code:
ContentValues contentValues = new ContentValues();
contentValues.put(DatabaseHelper.COLUMN_DEFAULT, "CASE WHEN " + DatabaseHelper.COLUMN_ID + " != " + id + " THEN 0 ELSE 1 END");
getContentResolver().update(BenefitsProvider.CITY_CONTENT_URI, contentValues, null, null);
Where id is an id of a city, which I would like to make the default one. The issue is that this query doesn't change the is_default column value at all. I'm sure that ContentProvider code is fine and it works properly with all other update cases.
Is it possible to have only one city at the same time with is_default column value being 1 using this approach? Is there any other way I can achieve this?

Categories

Resources