I wanted to do query in table for field id with some vales like 1,5,4,11 which will come from previous screen according to selection.
cursor = database.query(tablename,
new String[] { "TopName" }, "id =?", new String[]{"2,3"}, null, null, null);
When I do like this, I am getting cursor count 0, with new String[]{"2"} I am getting value I want for all ids with values in string array like OR which have value in that column.
You can use the IN operator like this,
cursor = database.query(tablename, new String[] {"TopName"}, "id IN(?,?)",
new String[]{"2","3"}, null, null, null);
The correct syntax for using the IN operator in Android's ContentProvider is as follows:
cursor = database.query(contentUri, projection, "columname IN(?,?)", new String[]{"value1" , "value2"}, sortOrder);
Alternatively, we can also use,
cursor = database.query(contentUri, projection, "columnName IN(?)", new String[] {" 'value1' , 'value2' "}, sortOrder);
Note that we need single quotes around each comma-separated value in the arguments for second case, otherwise the whole string will be treated as one value for the column. The SQL will treat it as
SELECT * FROM table WHERE columnName IN ('value1,value2')
instead of the correct syntax
SELECT * FROM table WHERE columnName IN ('value1' , 'value2')
VolkerK was first to correctly answer the question, but for the sake of completeness here is a full example of how to use the IN operator:
cursor = database.query(tablename,
new String[] { "TopName" }, "id IN (?)", new String[]{"2,3"}, null, null, null);
Use the IN operator instead of equality comparison (=).
For the SelectionArgs section I think you need to change:
new String[]{"2,3"}
To
new String[]{"2","3"}
I would like to put this here since a compendium of answers helped me putting multiple (unknown) values in SQLiteDatabase.query() and the one-question-mark did not work for me. Hope helps anyone
// API > 24
protected String attributesAsMarks(String[] attributes) {
List<String> marks = Collections.nCopies(attributes.length, "?");
return marks.stream().collect(Collectors.joining(","));
}
// I'm using API > 15
protected String attributesAsMarks(String[] attributes) {
StringBuilder sb = new StringBuilder();
String separator = "";
for (String s : attributes) {
if (s == null) continue;
sb.append(separator).append("?");
separator = ",";
}
return sb.toString();
}
Thanks to
#Lalit
https://stackoverflow.com/a/5600690/1358777
https://stackoverflow.com/a/38546936/1358777
https://stackoverflow.com/a/524089/1358777
Related
I don't know what's wrong with my code I follow the rule but I get wrong result. I want to search db and find all rows data but I only get last row from sqlite. my code to search database is bellow:
public ArrayList<ArrayList<ContractSaveDataFromDB>> ActiveContractData(String phone, String numberId)
{
ArrayList<ContractSaveDataFromDB> UserData = new ArrayList<ContractSaveDataFromDB>();
ArrayList<ArrayList<ContractSaveDataFromDB>> SendUserData =
new ArrayList<ArrayList<ContractSaveDataFromDB>>();
SQLiteDatabase db = this.getReadableDatabase();
String whereClause = "phone = ? AND numberId = ?";
String[] whereArgs = new String[]{
phone,
numberId
};
String orderBy = "activeContract";
Cursor res2=db.query("usersAccount",null,whereClause,whereArgs,null,null,orderBy);
res2.moveToFirst();
do{
UserData.clear();
int index;
ContractSaveDataFromDB contractSaveDataFromDB=new ContractSaveDataFromDB();
index = res2.getColumnIndex("buyAmount");
String buyAmount = res2.getString(index);
contractSaveDataFromDB.setBuyAmount(buyAmount);
UserData.add(contractSaveDataFromDB);
SendUserData.add(UserData);
} while(res2.moveToNext());
res2.close();
db.close();
return SendUserData;
I don't know what's wrong. I appreciate if you help me to solve my problem.
you already added where clause so maybe it is filtering your results try to remove it by change this
Cursor res2=db.query("usersAccount",null,whereClause,whereArgs,null,null,orderBy);
to this
Cursor res2=db.query("usersAccount",null,null,null,null,null,orderBy);
I believe that your issues is that you are trying to use an ArrayList of ArrayList of ContractSaveDataFromDB objects.
I believe that an ArrayList of ContractSaveDataFromDB objects would suffice.
It would also help you if you learnt to do a bit of basic debugging, as an issue could be that you are not extracting multiple rows.
The following is an alternative method that :-
uses the ArrayList of ContractSaveDataFromDB objects,
introduces some debugging by the way of writing some potentially useful information to the log
and is more sound, as it will not crash if no rows are extracted
i.e. if you use moveToFirst and don't check the result (false means the move could not be accomplished) then you would get an error because you are trying to read row -1 (before the first row) as no rows exists in the cursor.
:-
public ArrayList<ContractSaveDataFromDB> ActiveContractData(String phone, String numberId) {
ArrayList<ContractSaveDataFromDB> SendUserData = new ArrayList<ContractSaveDataFromDB>();
SQLiteDatabase db = this.getReadableDatabase();
String whereClause = "phone = ? AND numberId = ?";
String[] whereArgs = new String[]{
phone,
numberId
};
String orderBy = "activeContract";
Cursor res2 = db.query("usersAccount", null, whereClause, whereArgs, null, null, orderBy);
Log.d("RES2 COUNT", "Number of rows in Res2 Cursor is " + String.valueOf(res2.getCount()));
while (res2.moveToNext()) {
ContractSaveDataFromDB current_user_data = new ContractSaveDataFromDB();
current_user_data.setBuyAmount(res2.getString(res2.getColumnIndex("buyAmount")));
Log.d("NEWROW", "Adding data from row " + String.valueOf(res2.getPosition()));
SendUserData.add(current_user_data);
}
res2.close();
db.close();
Log.d("EXTRACTED", "The number of rows from which data was extracted was " + String.valueOf(SendUserData.size()));
return SendUserData;
}
If after running you check the log you should see :-
A line detailing how many rows were extracted from the table
A line for each row (if any were extracted) saying Adding data from row ? (where ? will be the row 0 being the first)
A line saying The number of rows from which data was extracted was ? (? will be the number of elements in the array to be returned)
I have the following code that works and gets a record from a database.
public Audit getAudit(SQLiteDatabase db, String projectId, String date,String type, int category) {
String[] columns = { "user_id", "submitted", "answers" };
String[] whereArgs = new String[]{projectId, date, type};
Cursor c = db.query("AUDITS", columns, "project_id = ? AND date = ? AND type = ?",whereArgs, null, null, null);
if (c != null)
{
Audit audit = new Audit(projectId, type, category, c.getString(c.getColumnIndex("user_id")), date, c.getInt(c.getColumnIndex("submitted")), c.getString(c.getColumnIndex("user_id")));
return audit;
}
return null;
}
But now I want to add another column to the Where clause, and this column holds an integer and not a string. So I can not add it to whereArgs array which holds strings. Is there a way that I can still use this method with mixing types or do I need to just do a raw query??
The Integer.toString() way seems to be best as "the values will be bound as Strings" in the query method. See the answer to
Android SQLite query with integer parameter
I have database which contains "date" column and "item" column.
I want that user could update specific row in the database.
I trying to do it with update method in SQLiteDatabase class.
My problem is that i dont know how to make update method find exactly the row i want.
I saw some example that use it with parameters from one word.
like this:
ourDatabase.update(tableName, cvUpdate, rowId + "=" + item , null);
My problem is that i want to update the row that have specific item and date. so the name of the item alone is not enough.
I tried this code below but its didnt work, hope youll can help me.
public void updateEntry(String item, String date) throws SQLException{
String[] columns = new String[]{myItem, myDate};
Cursor c = ourDatabase.query(tableName, columns, null, null, null, null, null);
long position;
ContentValues cvUpdate = new ContentValues();
cvUpdate.put(date, myDate);
cvUpdate.put(item, myExercise);
int itemAll = c.getColumnIndex(myItem);
int dateAll = c.getColumnIndex(myDate);
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()){
if (c.getString(itemAll).equals(myItem) && c.getString(dateAll).equals(myDate))
{
position = c.getPosition();
break;
}
}
ourDatabase.update(tableName, cvUpdate, rowId + "=" + position , null);
}
First, the columns String[] is supposed to contain column names, such as "_ID", or whatever are the column names you have used. Given that you compare the content of the column myItem with the object myItem, I assume there is a confusion somewhere here.
Secondly, rowId and position are different things in SQL, especially if you delete rows, as the row id usually is autoincrement, and especially since your query is not explicitely sorted. Replacing c.getPosition() by c.getLong(c.getColumnIndex(ID_COLUMN)) would make more sense.
Thirdly, sql is nice because you can query it. For example, rather than get all items and loop to find the matching date and item, you can :
String whereClause = ITEM_COLUMN + " = ? and " + DATE_COLUMN + " = ?";
String[] whereArgs = new String[] { item, date };
Cursor c = ourDatabase.query(tableName, columns, whereClause, whereArgs, null, null, null);
instead of your for loop.
Forthly, you can even make the query in the update :
String whereClause = ITEM_COLUMN + " = ? and " + DATE_COLUMN + " = ?";
String[] whereArgs = new String[] { item, date };
ourDatabase.update(tableName, cvUpdate, whereClause, whereArgs);
Extra tip: use full caps variable names for contants such as column names, it help with readability.
Is possible to use an IN clause for a content provider?
I am currently using
cursor = contentResolver.query(CONTENT_URI, PROJECTION, "field IN (?)", new String[] { argsBuilder.toString() }, null);
If i remove the (?) and just use ? I get an error.
I get 0 count in my cursor.
If I type manually and execute the query in sqlite3 it works.
Help?
When using the IN operator, you need to have one ? separated by a comma per argument you provide in your selectionArgs array. E.g.:
String[] selectionArgs = {"red", "black"};
String selection = "color IN (?, ?)";
The following picks the right count and the proper args:
int argcount = 2; // number of IN arguments
String[] args = new String[]{ 1, 2 };
StringBuilder inList = new StringBuilder(argcount * 2);
for (int i = 0; i < argcount; i++) {
if(i > 0) {
inList.append(",");
}
inList.append("?");
}
cursor = contentResolver.query(
CONTENT_URI,
PROJECTION,
"field IN (" + inList.toString() + ")",
args,
null);
If your arguments are numbers only, this works as well:
Iterable args = ...; // any array, list, set, ...
cursor = contentResolver.query(CONTENT_URI, PROJECTION, "field IN (" + TextUtils.join(",", args) + ")", null, null);
This is a code snippet from my application built in Kotlin, the params array is for illustration purposes only as the parameters come from elsewhere in the code.
The problem with most of the proposed solutions is that they result in the loss of the SQL injection prevention that the use of placeholders provides, so I only use an expression that returns an array of "?" and whose quantity matches the array of provided parameters and then becomes a comma separated String.
That way, the delivered string is a string of placeholders and not the parameters directly.
Sorry for my first answer write in spanish.
var params = arrayOf("1789","1787","1694","1784")
applicationContext.contentResolver.query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
null,
"_ID IN (" + Array(params.size) { "?" }.joinToString() + ")",
params,
null
)
I am working on a database with sqllite in an android app
I want to retrieve sm data using a like clause
ex:
Cursor c = myDB.query(MY_DATABASE_TABLE, null, " SongName LIKE '%"+"=?"+"%'" ,
new String[]{match_str}, null, null,"SongHit DESC");
It should give all SongName starting with match_str but its not working.Why?
This:
" SongName LIKE '%"+"=?"+"%'"
Will end up looking like this when the SQL interpreter sees it:
" SongName LIKE '%=?%'"
And that will match any SongName that contains a literal "=?" and I don't think that's anything like what you want.
A % matches any sequence of characters in an SQL LIKE, it is essentially the same as .* in a regular expression; so, if you want to match at the beginning then you don't want a leading %. Also, your ? placeholder needs to be outside the single quotes or it will be interpreted as a literal question mark rather than a placeholder.
You want something more like this:
String[] a = new String[1];
a[0] = match_str + '%';
Cursor c = myDB.rawQuery("SELECT * FROM songs WHERE SongName LIKE ?", a);
If you wanted to be really strict you'd also have to escape % and _ symbols inside match_str as well but that's left as an exercise for the reader.
Try this:
String[] args = new String[1];
args[0] = "%"+song+"%";
Cursor friendLike = db.rawQuery("SELECT * FROM songs WHERE SongName like ?", args);
No need for the equal sign and you should be able to include the ? right in the string without the need for the + operator. The where clause should just be:
"SongName LIKE '%?%'"
and if mu is too short is correct and you only want starting with...
"SongName LIKE '?%'"
hi Are you getting any exception while executing the above query. Try by removing the "=" symbol infront of the question mark in the like condition. Else try using
db.rawQuery(sql, selectionArgs)
This works perfectly for me...
"Songname LIKE ? "...
cursor = database.rawQuery(query, new String[]{"%" + searchTerm + "%"});
If you wish to use query() instead of rawQuery(), you can do it like so:
// searchString is the string to search for
final String whereClause = "MyColumnName" + " like ?";
String[] whereArgs = new String[]{"%" + searchString + "%"};
Cursor cursor = sqLiteDatabase.query("MyTableName",
null, // columns
whereClause, // selection
whereArgs, // selectionArgs
null, // groupBy
null, // having
null, // orderBy
null); // limit
a simple way is to use the concatenate operator ||
"SongName LIKE '%'||?||'%'"
so there is no need to edit the match_str.
Cursor c = myDB.query(MY_DATABASE_TABLE, null, " SongName LIKE '%'||?||'%'" ,
new String[]{match_str}, null, null,"SongHit DESC");
from https://stackoverflow.com/a/46420813/908821