(Feel free to improve the question title if you can think of something better.)
Question: Consider the following SQLite query:
SELECT COUNT(*)
FROM (SELECT 1 AS value UNION SELECT 2 AS value)
WHERE value <= ?
When I use 1
as the parameter, I expect the query to yield 1
, yet it yields 2
. Why does this happen?
Additional information:
This is a minimal working example to reproduce the issue (Android):
Cursor c = db.rawQuery(
"SELECT COUNT(*) " +
" FROM (SELECT 1 AS value UNION SELECT 2 AS value) " +
" WHERE value <= ? ",
new String[] {String.valueOf(1)});
c.moveToFirst();
Log.i("", "Result: " + String.valueOf(c.getInt(0)));
It might have to do with the fact that the parameter is passed as a string, but, alas, there is no other way to pass parameters to the SQLite API, so I guess I'm not doing anything "wrong" here and it's SQLite's job to convert the value appropriately. I've also observed the following when using a non-parameterized version of the query (this might or might not be relevant for the issue):
SELECT COUNT(*)
FROM (SELECT 1 AS value UNION SELECT 2 AS value)
WHERE value <= 1 -- yields 1
SELECT COUNT(*)
FROM (SELECT 1 AS value UNION SELECT 2 AS value)
WHERE value <= '1' -- yields 2
It's said in the
rawQuery
documentation:And, quoting the SQLite doc:
As both 1 and 2 are integers, they're both less than '1' (TEXT value). That's why this statement:
... returns 1 in SQLite.
You should probably use ...
... instead. Or you can use the fact that all mathematical operators cast both operands to the NUMERIC storage class with
WHERE value <= + ?
, but this is less clean, imo.Note that in this query:
... the value of
?
will get its affinity adjusted to the affinity of_id
column - hence they will be compared as numbers, if_id
is NUMERIC.