Multiple SelectionArgs for query - android

I have a String[] that looks like {1, 2, 3 ..} (a string of IDs).
I want to build a query in Android to obtain all the entries that match the IDs.
Here my code:
Cursor idFoodCursor = getContext().getContentResolver().query(
uriFood,
null,
CookingContract.FoodEntry.COLUMN_NAME + " LIKE ?",
new String[]{selectionArgs},
null
);
if (idFoodCursor.moveToFirst()) {
List<String> ids = new ArrayList<String>();
while (!idFoodCursor.isAfterLast()) {
ids.add(idFoodCursor.getString(idFoodCursor.getColumnIndex(CookingContract.FoodEntry._ID)));
idFoodCursor.moveToNext();
}
idFoodCursor.close();
//Convert the ArrayList in String[]
String[] idSelectionArg = new String[ids.size()];
ids.toArray(idSelectionArg);
return new CursorLoader(
getContext(),
uriFood,
FOOD_COLUMNS,
CookingContract.FoodEntry._ID + " = ?",
idSelectionArg,
sortOrder
);
}
The last query doesn't work because I should add as many "?" as my IDs in the array:
Caused by: java.lang.IllegalArgumentException: Cannot bind argument at index 3 because the index is out of range. The statement has 1 parameters.
How can I fix the problem, taking into account what I want to get? (the correspondence of all the ids in the table)

All the over-mentioned code can be replaced with:
return new CursorLoader(
getContext(),
uriFood,
FOOD_COLUMNS,
"_id IN (SELECT _id FROM food WHERE name LIKE ?)",
new String[] {selectionArgs},
sortOrder
);
That does the job I wanted.

public class Constants {
public static final String JOB_STATUS_CANCELLED = "Cancelled";
public static final String JOB_STATUS_COMPLETE = "Complete";
}
selection = JobListContract.JobEntry.COLUMN_NAME_JOB_STATUS + " NOT IN ( ? , ? ) ";
// The spaces matter!!!!
selectionArgs = new String[]{ Constants.JOB_STATUS_COMPLETE, Constants.JOB_STATUS_CANCELLED };
c = db != null ? db.query(
JobListContract.JobEntry.TABLE_NAME, // The table to query
projection, // The columns to return
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
JobListContract.JobEntry.COLUMN_NAME_ENTRY_ID + " desc" // The sort order
) : null;

Related

How to put multiple where clause in a query?

I have this code below in which gets all data having the 'grpnumber'. my question is: How can I get 2 where clause? i want to get the records having the group number and calories?
String[] projection = {
FoodReaderContract.FoodGroupEntry._ID,
FoodReaderContract.FoodGroupEntry.COLUMN_GROUP_NUMBER,
FoodReaderContract.FoodGroupEntry.COLUMN_GROUP_FOODNAME,
FoodReaderContract.FoodGroupEntry.COLUMN_GROUP_TIMEOFDAY,
FoodReaderContract.FoodGroupEntry.COLUMN_GROUP_CALORIE
};
// Filter results WHERE "title" = 'My Title'
String selection = FoodReaderContract.FoodGroupEntry.COLUMN_GROUP_NUMBER
+ " = ?";
String[] selectionArgs = {grpnumber};
//String selection = FeedReaderContract.FooEntry._ID + " = ?";_
//Int[] selectionArgs = {2};
// How you want the results sorted in the resulting Cursor
String sortOrder =
FoodReaderContract.FoodGroupEntry.COLUMN_GROUP_NUMBER + " DESC";
Cursor cursor = db.query(
FoodReaderContract.FoodGroupEntry.GROUP_TABLE_NAME, // The table to query
projection, // The columns to return
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
);
You can use the AND keyword.
String selection = FoodReaderContract.FoodGroupEntry.COLUMN_GROUP_NUMBER + " = ? "
+ " AND " + FoodReaderContract.FoodGroupEntry.COLUMN_GROUP_CALORIE + " = ?";
String[] selectionArgs = {String.valueOf(grpnumber), String.valueOf(calorie)};

Complex queries with SQLite in Android

I have a table with 3 columns "ID", "NAME" & "STATUS". I would like to execute a query on my database where I can get only one entry of "ID" which is located at the top row. I have a working sql query,
"SELECT TOP 1 ID from SAMPLE_TABLE WHERE Status='PENDING' ORDER BY ID ASC;"
This is so far what I implemented in android,
// Getting pending items
public int pendingContact() {
SQLiteDatabase db = this.getWritableDatabase();
Cursor mCount = db.query(
TABLE_CONTACTS ,
new String[] { "id" } ,
"status = ?" ,
new String[] { "PENDING" } ,
null ,
null ,
null
);
mCount.moveToFirst();
int count = mCount.getInt(0);
mCount.close();
return count;
}
Al through it gives the desired output but I would like to know if there is any other way of doing this more efficiently.
You can use Limit
public Cursor query (String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit)
limit - Limits the number of rows returned by the query, formatted as LIMIT clause. Passing null denotes no LIMIT clause.
You can do this:
Cursor mCount = db.query(TABLE_CONTACTS, new String[] { "id" }, "status = ?", new String[] { "PENDING" }, null, null, "id ASC", "1");
This will keep you from acquiring more data than you need.
When you use ORDER BY, the database will read and sort all PENDING items before it can return the first one.
When using MIN, nothing but the smallest value must be stored temporarily:
SELECT MIN(id) FROM Contacts WHERE Status = 'PENDING'
In code:
Cursor mCount = db.rawQuery("SELECT MIN(id) FROM Contacts WHERE Status = ?",
new String[] { "PENDING" });

Android Sqlite concat two columns

I have made the concatenation so far, but in the results, it displays
UncleSam.
What I want to do is to put a space between the two columns so the result would be
Uncle Sam.
This is the code I'm working on:
public Cursor getAllPatients()
{
Cursor localCursor = //
this.myDataBase.query(DB_TABLE, new String[] {
KEY_ID, KEY_FNAME + "||" + KEY_LNAME, KEY_DIAGNOSIS, KEY_LASTFFUP }, null, null, null, null, null);
if (localCursor != null)
localCursor.moveToFirst();
return localCursor;
}
from DBHelper.java
and
Cursor cursor = dbHelper.getAllPatients();
String[] data = new String[]{
DBHelper.KEY_FNAME + "||" + DBHelper.KEY_LNAME, DBHelper.KEY_DIAGNOSIS, DBHelper.KEY_LASTFFUP};
//
int[] to = new int[] {R.id.fullname, R.id.diagnosis, R.id.lastffup};
dataAdapter = new SimpleCursorAdapter(this, R.layout.custom_row, cursor, data, to, 0);
from my MainActivity.
Any help will do. Thanks.
You can concat like this:
Cursor localCursor = this.myDataBase.rawQuery("SELECT (KEY_FNAME || ' ' || KEY_LNAME) AS fullname, KEY_ID, KEY_DIAGNOSIS, KEY_LASTFFUP FROM DB_TABLE");
Your concated full name will be in the cursor column 'fullname'.
In main activity:
String[] data = new String[]{ "fullname", DBHelper.KEY_DIAGNOSIS, DBHelper.KEY_LASTFFUP};
(You should probably assign a DBHelper constant for "fullname").
Android Sqlite concat two columns
After a little conversation with author of this thread i suggest you to don't concat columns (you really don't need it) and concat Strings retrieved from Cursor. Your statement will be more human-readable and solution cleaner.
Explanation:
Generally is very useful and efficient approach to represent your table on application layer with objects which will represent tables. For example if you had table User, so create new class User and columns in table will be equal to properties in this class. This way is i guess pretty elegant (if someone else will see your code, he won't be confused and scared)
Finally you can simply concat fname and lname when you'll add them to ListAdapter
So i prefer this way:
List<User> users = new ArrayList<User>();
User u = null;
String query = "select * from Table";
Cursor c = db.rawQuery(query, null);
if (c != null && c.moveToFirst()) {
do {
u = new User();
u.setFirstName(c.getString(c.getColumnIndex("fname")));
u.setLastName(c.getString(c.getColumnIndex("lname")));
...
users.add(u);
} while (c.moveToNext());
}
And then somewhere in ListAdapter you can do:
textView.setText(u.getFirstname() + " " + u.getLastName());
Hope it helps.
I finally got it working.
public Cursor getAllPatients()
{
Cursor localCursor = //
this.myDataBase.query(DB_TABLE, new String[] {
KEY_ID, KEY_FNAME + "|| ' ' ||" + KEY_LNAME, KEY_DIAGNOSIS, KEY_LASTFFUP }, null, null, null, null, null);
if (localCursor != null)
localCursor.moveToFirst();
return localCursor;
}
and
Cursor cursor = dbHelper.getAllPatients();
String[] data = new String[]{
DBHelper.KEY_FNAME + "|| ' ' ||" + DBHelper.KEY_LNAME, DBHelper.KEY_DIAGNOSIS, DBHelper.KEY_LASTFFUP};
//
int[] to = new int[] {R.id.fullname, R.id.diagnosis, R.id.lastffup};
dataAdapter = new SimpleCursorAdapter(this, R.layout.custom_row, cursor, data, to, 0);

how to retrieve a specific string data from sqlite database by using 2 string arguments?

this is my code used which i use for making method
String item = item1.getText().toString();
item = item.toLowerCase();
String date = getDate();
edited = new Datahelper(this);
edited.open();
String returnedprice = edited.getprice(item,date);
String returneddetail = edited.getdetail(item,date);
edited.close();
price.setText(returnedprice);
details.setText(returneddetail);
and this is my code of method that i am using for getting that string but here i dont know how to use the 2nd date string so that the string price that return is from a row that contains that item and that date.. please give me the code of how to do it..
public String getprice(String item ,String date) {
// TODO Auto-generated method stub
String[] columns = new String[]{KEY_ROWID,
KEY_CATEGORY,KEY_DATE,KEY_PRICE,KEY_DETAILS};
Cursor v =ourDatabase.query(DATABASE_TABLE, columns, KEY_CATEGORY + " ='" + item
+"'",null,null, null, null);
if(v!=null){
String price = v.getString(3);
return price;
}
return null;
}
public String getdetail(String item,String date) {
// TODO Auto-generated method stub
String[] columns = new String[]{KEY_ROWID,
KEY_CATEGORY,KEY_DATE,KEY_PRICE,KEY_DETAILS};
Cursor v =ourDatabase.query(DATABASE_TABLE, columns, KEY_CATEGORY + " ='" + item +
"'",null,null, null, null);
if(v!=null){
String detail = v.getString(4);
return detail;
}
return null;
}
So probably you want to use two arguments in select query so:
You can use two methods:
rawQuery()
query()
I will give you basic example for both cases.
First:
String query = "select * from Table where someColumn = ? and someDateColumn = ?";
Cursor c = db.rawQuery(query, new String[] {textValue, dateValue});
Explanation:
So i recommend to you use ? that is called placeholder.
Each placeholder in select statement will be replaced(in same order so first placeholder will be replaced by first value in array etc.) by values from selectionArgs - it's String array declared above.
Second:
rawQuery() method was easier to understand so i started with its. Query() method is more complex and has a little bit more arguments. So
columns: represents array of columns will be selected.
selection: is in other words where clause so if your selection is
KEY_COL + " = ?" it means "where " + KEY_COL + " = ?"
selectionArgs: each placeholder will be replaced with value from this
array.
groupBy: it's multi-row (grouping) function. more
about
having: this clause is always used with group by clause here is
explanation
orderBy: is clause used for sorting rows based on one or multiple
columns
Also method has more arguments but now you don't need to care about them. If you will, Google will be your friend.
So let's back to explanation and example:
String[] columns = {KEY_COL1, KEY_COL2};
String whereClause = KEY_CATEGORY " = ? and " + KEY_DATE + " = ?";
String[] whereArgs = {"data1", "data2"};
Cursor c = db.query("Table", columns, whereClause, whereArgs, null, null, null);
So whereClause contains two arguments with placeholder for each. So first placeholder will be replaced with "data1" and second with "data2".
When query is performed, query will look like:
SELECT col1, col2 FROM Table WHERE category = 'data1' AND date = 'data2'
Note: I recommend to you have look at Android SQLite Database and ContentProvider - Tutorial.
Also i recommend to you an usage of placeholders which provide safer and much more readable and clear solutions.
You should read any SQL tutorial to find out what a WHERE clause it and how to write it.
In Android, the selection parameter is the expression in the WHERE clause.
Your query could be written like this:
c = db.query(DATABASE_TABLE, columns,
KEY_CATEGORY + " = ? AND " + KEY_DATE + " = ?",
new String[] { item, date },
null, null, null);

row id from database

i am trying to do a query of my database for a string lets call it "Test" and then find out what row that particular string is in and save that number to use. I thought i had this figured out before but now it is not working for some reason and i get an error saying no such column "Test".
here is my code
public String getRow(String value){
ContactDB db = new ContactDB(this);
db.open();
Cursor curs = db.getId(value);
String test = curs.getString(curs.getColumnIndex(db.NAME));
curs.close();
Log.v("Contact", "Row ID: " + test);
db.close();
return test;
}
"Test" is sent into that as value
this is in my database
//---retrieve contact id---
public Cursor getId(String where){
Cursor c = db.query(DATABASE_TABLE, new String[] {ID},where,null,null,null,null);
if (c != null)
c.moveToFirst();
return c;
}
i dont remember changing anything from when i first tested it so i dont know why it wont work now
There are 2 errors that i could notice:
In the query
Cursor c = db.query(DATABASE_TABLE, new String[] {ID},where,null,null,null,null);
only the ID column is selected whereas you are trying to fetch details for column NAME
String test = curs.getString(curs.getColumnIndex(db.NAME));
include the name column as well in the select clause : something like
Cursor c = db.query(DATABASE_TABLE, new String[] {ID,NAME},where,null,null,null,null);
In the where clause you need to write the condition string excluding "where"
in your case String where contains value "Test". Hence the filter condition should be as
String whereClasue = NAME + " = '" + where + "'";
The query should be something like this:
public Cursor getId(String where){
Cursor c = db.query(DATABASE_TABLE, new String[] {ID,PHONE_NUMBER,NAME},NAME + " = '" + where + "'",null,null,null,null);
if (c != null)
c.moveToFirst();
return c;
}

Categories

Resources