I am trying to get data in an order by executing rawQuery with join conditions. but i am unable to get expected result.
below is my query.
String queryString = "SELECT DISTINCT B.MakeID , B.Make FROM MakeList B JOIN BodyStyle BS ON B.Makeid = BS.makeid AND BS.Year = 2012 ORDER BY B.Make ASC";
First thing is no need to write ASC coz it is bydefault ascending order to display result so write simple ORDER BY B.Make and second thing specify what you need in results and post database fields also.
Verify that your databases match. You may have db data that your SQLite Manager is accessing that may be different that what is on your Android device. That is probably causing your unexpected behavior.
Related
I am fetching a string from Database using the column id. When I enter a query in SQLite DB Browser it returns what is need but the same query returns nothing when coded through Java.
My Data Base contains a table named drugs which has 3 columns i.e. drug_id, drug_name and drug_overview. Using drug_id i am fetching drug_overview. I have tried the query in db browser which returns me the correct string from drug_overview but the same query returns nothing when coded through java.
SQLite DB Browser query:
SELECT * FROM drugs Where drug_id = 50;
JAVA CODE:
String query105 = "SELECT * FROM drugs Where drug_id = " + drug_id;
Log.e("TESTDB1","Drugs table query: " + query105);
Cursor c105 = db.rawQuery(query105,null);
if (c105 != null){
while (c105.moveToNext()){
String overview = c105.getString(c105.getColumnIndexOrThrow("drug_overview"));
Log.e("TESTDB1","Overview: " + overview);
}
c105.close();
}
Expected result is Overview: Acyclovir is an antiviral drug. It slows the growth and spread of the herpes virus in the body. It will not cure herpes, but it can lessen the symptoms of the infection.Acyclovir is used to treat infections caused by herpes viruses, such as genital herpes, cold sores, shingles, and chicken pox, as well as varicella (chickenpox), and cytomegalovirus.Acyclovir may also be used for purposes not listed in this medication guide.
But the actual result is Overview:
empty
. When i change the id in my query it gives the correct result from a different drug.
I am afraid that your problem may be with the actual data itself as Mike said in comment, I think your database in the files is old and you haven't copied the latest to folder. Try to re-install and delete old database
Your query returns 0 or 1 lines so I think you should use c105.moveToFirst() instead of c105.moveToNext(). moveToNext is supposed to be used for a list, not for a single entry. Do something like:
if (c105.moveToFirst()){
String overview = c105.getString(c105.getColumnIndex("drug_overview"));
// do something with the result
}
c105.close();
I am building an Android app that uses a SQLite database.
For this one task I have to run a query that looks like this:
SELECT item.id, item.price, t1.quantity
FROM item, (SELECT id, price
FROM list
WHERE list.state = 'sold') t1
WHERE item.id = t1.id
So far, I have tried:
Cursor c = resolver.query(uriRawQuery, null, selection, null, null)
where uriRawQuery is used to tell the ContentProvider that it should perform a db.rawQuery(selection, null) and selection is a string similar to the query above.
The problem is no data is returned into the Cursor. When I call c.moveToFirst() I get false.
The weird thing is that if I open the database file in SQLite Manager and run the exact same query I get results.
I know I can modify the query to make a join between the original list and item tables but I find it to be less efficient that way.
Any ideas would be very appreciated as I have spent too man hours on this already.
EDIT
I know what a join is, what I said is that it is a lot more efficient if I do it like this instead of using the entire list table.
I forgot a very important aspect
The WHERE clause looks like
" WHERE list.state = 'sold' and list.name like '" + arg + "%'"
where arg is a string.
I managed to solve the problem, I still don't know why this was happening but at least I got the Cursor to actually select the rows.
After many trials I thought about ditching the syntax above and write this instead:
" WHERE list.state = 'sold' and list.name like ? "
and move the argument in
selectionArgs = new String[]{arg + "%"}
I am going to wait a while before accepting the answer, in case someone provides an explanation as to why even though both queries look exactly the same they get different results.
I'm passing the below statement as a rawQuery in Android:
SELECT DISTINCT ltUsers._id,ltUsers.NAME,ltUsers.GLOBAL_ID, ltGroups.GROUP_NAME
FROM ltUsers
JOIN ltGroups ON (ltUsers.GROUP_ID = ltGroups.GLOBAL_ID)
WHERE ltgroups.GLOBAL_ID = ? " +
ORDER BY ltUsers.NAME ASC,ltgroups.GLOBAL_ID ASC;
With the rawQuery as follows:
Cursor c = db.rawQuery(sql,args)
It works just fine if I pass a value to the parameter, e.g.
String[] args = new String[]{"2"}
However, I also want to be able to show all rows, unlimited by the GLOBAL_ID in the WHERE clause. Testing on a dump of my SQLite database outside of Android - as well as in Android by just writing the parameter directly into the statement - shows the following clause to be a valid way to do this:
WHERE ltGroups.GLOBAL_ID = ltGroups.GLOBAL_ID
Yet when I pass the field reference ltGroups.GLOBAL_ID or [ltGroups].[GLOBAL_ID] as a parameter it fails to return any rows in the rawQuery. Any ideas on why this might be happening? Happy to produce any extra information.
Parameters always replace specific values, not anything else.
When you put the string "ltGroups.GLOBAL_ID" into the parameters array, it is interpreted as exactly that, a string.
(To show all records, just omit the WHERE clause.)
I need to execute an "in place" update SQL Query on an SQLite database in my android application. The query is of the form:
update table T set column = column + 1 where someOtherColumn = aValue
I tried executing this query with SQLiteDatabase.rawQuery(updateQuery, "someOtherColumn = ?", new String{}[aValue]) but I find that the column is not incremented. When I run the same query with the usual SQLiteDatabase.update(...) it works fine, but this requires me to fetch the old column value, update it outside and then execute update() which is probably less efficient since it requires a select and then an update.
Is there some way I can update "in place" by using the first query?
Thanks.
Is there some way I can update "in place" by using the first query?
That's not a query. It's an UPDATE statement. It does not return a result set. Use it with execSQL(), not rawQuery().
but this requires me to fetch the old column value, update it outside and then execute update() which is probably less efficient since it requires a select and then an update
This is the way all SQL databases work. Now, those that offer stored procedures may be able to let you do an UPDATE and a SELECT in one request, but it is still an UPDATE and a SELECT. Furthermore, SQLite does not support stored procedures, at least when I last looked.
Android's API provides a clean mechanism via SQLite to make queries into the contact list. However, I am not sure how to limit the results:
Cursor cur = ((Activity)mCtx).managedQuery(
People.CONTENT_URI,
columns,
"LIMIT ? OFFSET ?",
new String[] { Integer.toString(limit), Integer.toString(offset) },
null
);
Doesn't work.
Actually, depending on the provider you can append a limit to the URI as follows:
uri.buildUpon().appendQueryParameter("limit", "40").build()
I know the MediaProvider handles this and from looking at recent code it seems you can do it with contacts too.
You are accessing a ContentProvider, not SQLite, when you query the Contacts ContentProvider. The ContentProvider interface does not support a LIMIT clause directly.
If you are directly accessing a SQLite database of your own, use the rawQuery() method on SQLiteDatabase and add a LIMIT clause.
I found out from this bug that Android uses the following regex to parse the LIMIT clause of a query:
From <framework/base/core/java/android/database/sqlite/SQLiteQueryBuilder.java>
LIMIT clause is checked with following sLimitPattern.
private static final Pattern sLimitPattern = Pattern.compile("\\s*\\d+\\s*(,\\s*\\d+\\s*)?");
Note that the regex does accept the format offsetNumber,limitNumber even though it doesn't accept the OFFSET statement directly.
I think you have to do this sort of manually. The Cursor object that is returned from the managedQuery call doesn't execute a full query right off. You have to use the Cursor.move*() methods to jump around the result set.
If you want to limit it, then create your own limit while looping through the results. If you need paging, then you can use the Cursor.moveToPosition(startIndex) and start reading from there.
You can specify the "limit" parameter in the "order" parameter, maybe even inside other parameters if you don't want to sort, because you'll have to specify a column to sort by then:
mContentResolver.query(uri, columnNames, null, null, "id LIMIT 1");