I use a ContentProvider
to speak with my application's database and I'm running into a bit of a problem.
I have a query that is slightly complicated. It looks something like this:
String sql =
"select " +
" tblHistory._id _id, " +
" tblHistory.item item, " +
" tblHistory.updated_on updated_on, " +
" (select _id from tblList " +
"where tblList.item = tblHistory.item) list_id, " +
" 1 priority, " +
"from " +
" tblHistory " +
"where " +
" tblHistory.status <> 'STATE_DELETING' and " + selection + " " +
"union " +
"select " +
" tblSearch._id _id, " +
" tblSearch.item item, " +
" -1 updated_on, " +
" (select _id from tblList " +
"where tblList.item = tblSearch.product_name) list_id, " +
" 2 priority, " +
"from " +
" tblSearch " +
"where " +
" not exists (select * from tblHistory " +
"where tblHistory.item = tblSearch.product_name) " +
"order by " +
" priority, _id asc";
c = mDb.rawQuery(sql, null);
Selection is:
String where = "tblHistory.user_id="
+ Integer.toString(intUserId)
+ " and tblHistory.item like '%"
+ strSearch + "%'";
My problem is my sub-queries. I have a constraint I need to add, but no good way of getting that constraint down the pipe to the method. I need to use the correct user_id on the sub-queries.
At this point, I think I have 2 options:
1) Parse out the user_id
substring from selection.
2) Use selectionArgs
as a hack to pass "user_id = " + Integer.toString(intUserId)
to the method.
Any other ideas?
I should note that while I'd rather not doing anything hack-ish, I have made my ContentProvider
private as it is intended to only be used by my application; so if I absolutely have to, I can.
when dealing with complex queries like this, a builder class can come handy. It avoids you having to convert them to String, hope this helps you.
public class SqlQueryBuilder {
private static final String SELECT = "SELECT";
private static final String COMA = " , ";
private static final String WHERE = " where ";
private static final String EQUALS = " = ";
private static final String NOT_EQUALS = " != ";
private static final String FROM = " FROM ";
private final StringBuilder mStrBuilder = new StringBuilder();
public void init() {
mStrBuilder.setLength(0);
}
public SqlQueryBuilder select(Object ...columns) {
mStrBuilder.append(SELECT);
for(Object column:columns) {
mStrBuilder.append(column);
mStrBuilder.append(COMA);
}
return this;
}
public SqlQueryBuilder where(Object conditionVar) {
mStrBuilder.append(WHERE);
mStrBuilder.append(conditionVar);
return this;
}
public SqlQueryBuilder equalsVal(Object equalsVal) {
mStrBuilder.append(EQUALS);
mStrBuilder.append(equalsVal);
return this;
}
public SqlQueryBuilder notEqualsVal(Object notEqualsVal) {
mStrBuilder.append(NOT_EQUALS);
mStrBuilder.append(notEqualsVal);
return this;
}
public SqlQueryBuilder from(Object from) {
mStrBuilder.append(FROM);
mStrBuilder.append(from);
return this;
}
public String build() {
final String sqlQuery = mStrBuilder.toString();
init();
return sqlQuery;
}
}
Usage is like below
{
SqlQueryBuilder sqlQueryBuilder = new SqlQueryBuilder();
String innerQuery = sqlQueryBuilder.select("_id").from("tblList")
.where("tblList.item").equalsVal("tblHistory.item").build();
String query = sqlQueryBuilder.select("tblHistory._id _id",
"tblHistory.item", "tblHistory.updated_on updated_on",
innerQuery + " list_id", "1 priority").build();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With