I'm trying to do a relatively simple bitwise query operation with SQLite on Android. When I use bind variables, I get no data returned when I believe should get some rows back. If I hardcode the bind variable's value directly into the SQL, it works just fine. I'm thinking I have some silly syntax issue somewhere, but I just can't see it.
So this code works just fine:
String selection = new String(FLAGS + " & 2 = 2");
cursor = db.query(TABLE_NAME, ALL_COLUMNS, selection,
null, null, null, null, null );
This code however (using bind variables), returns no rows:
String selection = new String(FLAGS + " & ? = ?");
String[] selectionArgs = new String[]{"2", "2"};
cursor = db.query(TABLE_NAME, ALL_COLUMNS, selection,
selectionArgs, null, null, null, null );
They both result into a syntactically identical query being built when I inspect the cursor's mQuery property through the debugger. The latter does have the mBindArgs property populated correctly as well. I'm at a loss as to how this could be failing. There are no exceptions thrown or anything, it just doesn't return any rows.
I can take the failing query, and manually swap the question marks for the two's and paste it into the ADB SQLite command line interface and it works just fine as well.
If I am right the second query produces following condition:
& '2' = '2'
instead of
& 2 = 2
Try replacing & with AND
Make sure you have no ? characters in FLAG constant.
Besides what is a point of this logical condition?
I was facing the same problem as yours. As radek-k said, the query compares string.
One solution that may be performed is to use the following:
String selection = new String(FLAGS + " & ? = (0|?)");
Related
With Android's SQLite, is it possible to do math calculations on column values in a where clause? For example, say I want to select only the rows that have even values in their column named mColumnName. The following approach didn't work for me.
query(mTable, mColumns, mColumnName+"%2=?", new String[]{"0"}, null, null, null, null)
Is there another way to achieve this?
Android binds all query arguments as strings, which sometimes produces bugs when using functions and operations that produce numeric results. Inlining the zero in your selection string should fix this:
query(mTable, mColumns, mColumnName + " % 2 = 0", null, null, null, null, null)
I had a problem with updating of a column's value at a particular row. I had written
Cursor c = mDb.rawQuery("UPDATE "+book+" SET footnotes='" + note + "' WHERE chapter="+chapter+" and verse="+verse+"", null);
c.close();
But on adding c.moveToFirst() it worked. Why is that?
Cursor c = mDb.rawQuery("UPDATE "+book+" SET footnotes='" + note + "' WHERE chapter="+chapter+" and verse="+verse+"", null);
c.moveToFirst();
c.close();
Why is c.moveToFirst() necessary here, any particular reason?
There is an explation for c.moveToFirst()
(What is The use of moveToFirst () in SQLite Cursors) which briefly suggests that using c.moveToFirst() does two things
allows you to test whether the query returned an empty set
moves the cursor to the first result
But how does the above two things help in updation?
Think of rawQuery() as a wrapper for the C library sqlite3_prepare_v2() that compiles the SQL but does not run it, while think of moveTo..() as a wrapper for sqlite3_step() that is required for actually executing the prepared statement.
Related: What is the correct way to do inserts/updates/deletes in Android SQLiteDatabase using a query string?
Hello Stackoverflow members!
There is a strange problem in my app. When there is a few db rows (more than 0) in the table, the query works good. when there is no rows in the table, the app crashes ,and then, if I remove these lines, the app works ok:
Cursor result = db.rawQuery("Select * from users ORDER BY `ID` DESC" ,null);
result.moveToFirst();
String lastuser = result.getString(resultSet2.getColumnIndex("username"));
I hope you can help me =]
It looks like the crash is caused by the result not having any rows. You can check how many rows you obtained by using the getCount method on your cursor. If it's zero, do not try to get results from an empty set.
You can read more about cursors here.
After making your query, the cursor will be before the first position. So you have to move it to the first position, as you already do it with result.moveToFirst(). However, if your result was empty, the there is no first position and you get an Exception.
What you could do is either test
if(result.moveToFirst()){
// here you can access the content
}
or you try it with a loop (that way you can also react on results with multiple rows)
while(result.moveToNext()){
String lastuser = result.getString(resultSet2.getColumnIndex("username"));
// here you can access ALL row entries one after another, or just the one row
}
Here is a clear tutorial on using SQLite – hope it helps
First change your query as(remove single quote from ID )
Cursor result = db.rawQuery("Select * from users ORDER BY ID DESC" ,null);
And as #Gooey suggest You can check how many rows you obtained by using the getCount.
So use
Cursor result = db.rawQuery("Select * from users ORDER BY ID DESC" ,null);
if ((result != null) && (result.getCount() > 0)) {
result.moveToFirst();
String lastuser = result.getString(resultSet2.getColumnIndex("username"));
}
And post logcat exception,if still problem occur.
If I write something into an edittext that contains single quote (') my program crashes. With this edittext I can search for things in my database and some of them contain this single qoute (or apostrophe whatever name it has but the point is that it's about the single qoute). I assume it has some special functions and this is why it crashes. Is there any option to ignore its function or solve this problem somehow?
for example, an item in my database:
cv.put(KEY_NAME, "Jonh's idea");
cv.put(KEY_HOTNESS, "amazing");
cv.put(KEY_MONEY, "500");
ourDatabase.insert(DATABASE_TABLE, null, cv);
Then when I search for it with this method:
return ourDatabase.query(DATABASE_TABLE, new String[] {"_id", "idea_name",},
"idea_name like " + "'%" + qq + "%'", null, null, null, null);
where qq is given by the user (for example Jonh's idea), it crahses. And yes, I get syntax error.
Sounds like the ' is causing an SQL injection of some sort... the ' is causing a syntax error in your SQL statement. There are several things you might consider double checking:
rawQuery() will not protect you from SQL injections, so avoid using it (rather, use the query, insert, update, and delete methods instead).
Prefer formatting your selection and selectionArgs as follows (as it will protect you from SQL injections):
selection = "col_1 = ?";
selectionArgs = new String[] { "value_1" };
(note that the values in the String[] replace the ?s in the selection string).
Set an inputType on your EditText to prevent users from entering these characters in the first place (i.e. if you only want users to enter numbers, then set android:inputType="number").
Overall, as long as you correctly make use of the Android methods in the SQLiteDatabase class, you shouldn't run into any problems with SQL injections (Android does a good job at cleaning this up for you). That said, if you don't choose to make use of these special-purpose methods, then you should check the content of the String at runtime and protect against characters such as ', ;, ", etc. by escaping them.
You can refer to this post for more information:
Android Single Quote In SQL With a LIKE StateMent
You need to use the selectionArgs argument to escape the string (so that the single quote in it doesn't break the SQL). Try something like this:
return ourDatabase.query(DATABASE_TABLE, new String[] {"_id", "idea_name",}, "idea_name like ?", new String[] { "%" + qq + "%" }, null, null, null);
It seems like SQL-injection. U have to escape your input.
One more jugaad. You can replace ' with `. You won't have to recheck your code. Just modify the following:
String input = edittext.getText().toString();
if(input.contains("'"))
{
input = input.replace("'", "`");
}
//now proceed with the database operation ...
This will enable the user to input text like RD's jugaad to RD`s jugaad
In my search module I am using SQLite database. Sometimes I'm searching more than two values. So I am using AND condition and sometimes searching only one value. These two cases I need to implement in a single query. Please help me.
This is the query:
Cursor dbcur = myDB.rawQuery("select * from "+dbtable+" where Status='"+item+"'AND ball_court='"+ball+"'AND Tovendor='"+vendor+"'", null);
Sometimes I am searching status and ball_court, tovendor and sometimes I am searching status only. How to solve this problem?
Build the query string in stages, rather than all at once. If you're always going to select against the status, put that in the basic WHERE clause, then add any additional expressions. Use parameters (which you can do with SQLiteDatabase.query) rather than concatenating values into the query itself to prevent SQL injection. dbtable better not come from untrusted sources (e.g. users, the database itself). My Java's a little rusty, but try something like the following to start:
List<String> argList = new LinkedList<String>();
String selection = "Status=?";
argList.add(item);
if (ball != null && ball.length()) {
selection += " AND ball_court=?";
argList.add(ball);
}
if (vendor != null && vendor.length()) {
selection += " AND Tovendor=?";
argList.add(vendor);
}
String[] argArray = new String[argList.length()];
argList.toArray(argArray);
// columns is a String[] of column names
Cursor dbcur = myDB.query(false, dbtable, columns, selection, argArray, null, null, null);
Rather than appending strings, you might want to use a StringBuilder.
As for SELECT *, read "What is the reason not to use SELECT *?"
You might be able to get some answers if you post a sample query as well as what you might search for! I didn't totally understand your question, as I would/should be able to help out.