I have different variants of a query. All value types are Strings! (don’t ask why…)
The first one might look like this:
SELECT * FROM item WHERE arg1=false
The string (“sqlWhere”) for the arg(s) looks like this:
“arg1=?”
The string for the arg(s)-Array (args) at index 0 looks like this:
“false”
This works fine. I’ve got 715 results.
Now, if i have something like this:
SELECT * FROM item WHERE (arg1=40 OR arg2=42) AND arg3=false
I’ll expect 110 results for this. But there aren’t any results, no Exception is thrown
If I’ll generate a raw query in Firefox SQLite Manager:
SELECT COUNT(*) FROM item WHERE (arg1=40 OR arg2=42) AND arg3=false
I’ll get the error: “no such column: false”
If I generate a query like this:
SELECT COUNT(*) FROM item WHERE (arg1=40 OR arg2=42) AND arg3="false"
It’ll not fail. BUT. I’m using selectionargs. I’ve read, that they should AVOID this situation. But they don’t. Even, If I put into the selectionargs for arg3 = “\”+”false”+”\”” or arg3 = “\’+”false”+”\'” or even arg3=”‘”+”false”+”‘” it won’t work. Maybe an android specific problem?
The value “false” comes from a list of values. It is initialized with an emty string.
Query-Method looks like this:
public List<Map<String,String>> getSearchResults(String sqlWhere, String[]args)
{
List<Map<String,String>> specs = new ArrayList<Map<String,String>>();
String[] specnames = this.getSpecNames();
Cursor cursor = mDb.query(dbSchema.SpecSchema.TABLE_NAME, specnames, sqlWhere, args, null, null, dbSchema.SpecSchema._ID + dbSchema.SORT_ASC);
cursor.moveToFirst();
while(!cursor.isAfterLast())
{
Map<String, String> temp = new HashMap<String, String>();
for(int i = 0; i < specnames.length; i++)
temp.put(specnames[i], cursor.getString(cursor.getColumnIndex(specnames[i])));
specs.add(temp);
cursor.moveToNext();
}
if(cursor != null)
cursor.close();
return specs;
}
The documentation for
SQLiteDatabase.query()says:When you execute this query:
and bind the arguments using the
selectionArgs-parameter, the integers and the boolean will be bound as strings. This is not the same as in your database. I know you said all your columns are of typeTEXT, but read the SQLite Documentation:That means, when you insert your integer values in your string-table, SQLite will convert those and store them as integers. The next important point is comparison:
The docs give the following example:
In your case that means the following:
TEXT-table gets integers inserted, which are then converted (and stored) asINTEGERs.TEXT-values (which are your integers). Those should be (but don’t need to be) converted toTEXT-values, because your table indicates it’s values are of typeTEXT.INTEGERtoTEXT, which is not equal and therefor doesn’t give you the correct results.To insert different data-types (other then string) into the SQLiteDatabase, use Prepared Statements.