I\'m trying to select some data from database and I have two slices of code to do it:
cursor = builder.query(db,
new String[]{\"col1\", \
You need to convert your int id
into string
before passing to your query because the parameter array is of type string. For example:
cursor = builder.query(db, new String[]{"col1", "col2", "col3"},
"id = ?", new String[]{String.valueOf(getSID(db))}, null, null, null);
The reason why it works in second type of query is because you are appending the integer value with string which automatically converts the int into String. For example:
int i = 10;
String s = i + ""; //now 10 is in string
That query parameters can only be strings is a horrible design error in the Android database API.
Despite what the documentation says, you should use parameters only for actual string values; integer values can be safely embedded directly into the SQL string. (For blobs, you must use a function that accepts ContentValues
.)
Please note that while SQLite uses dynamic typing, values of different types do not compare equal in most cases (SELECT 42='42';
returns 0
).
There are some cases where SQLite does automatically convert values due to type affinity (in your case, this would happen if you declared the id
column as INTEGER
), but this is rather counterintuitive, so it should not be relied upon.
According to SQLite documentation,
Any column in an SQLite version 3 database, except an INTEGER PRIMARY KEY column, may be used to store a value of any storage class.
In context of my case, that means that we can't be sure what data type will be stored in columns. If you can control and convert data types when they're putting into database - you can convert id
values to TEXT
when adding data to database and use selectionArgs
easily. But it's not an answer for my question, because I have to deal with database content as is.
So, possible solutions:
a) embed integer values in selection
string without wrapping them into '
:
cursor = builder.query(db,
new String[]{"col1", "col2", "col3"},
"id = " + getSID(db), null, null, null, null);
b) cast values from selectionArgs: CAST(? as INTEGER)
or CAST(id AS TEXT)
. I think, converting column to TEXT
is better solution, because right operand is always TEXT
, but the left one can be anything. So:
cursor = builder.query(db,
new String[]{"col1", "col2", "col3"},
"CAST(id AS TEXT) = ?",
new String[]{getSID(db)}, null, null, null);