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.
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 have problems in updating rows in SQLite database in my Android application. It works successfully only, if I update it two times. But when I try to do it on the third time, it doesn't update the same row anymore.
LogCat doesn't show any exceptions. db.update() returns '1'.
I've searched similar issues on StackOverflow and the web. People advic]sed to remove db.close(); from database-helper, because I call it several times, or to use db.update method instead of db.rawQuery() or db.execSQL().
I also tested my query in SQLite client, and it works as it's supposed to.
Here is code of simple database-helper method:
public int updateEventDoneMark(Event event)
{
ContentValues args = new ContentValues();
args.put("completed", event.getCompleted());
return db.update("Event", args, "id" + "='" +event.getId() + "'", null);
}
Is there some SQLite-related issue I should know while I update one database entry several times in a row?
What does your content provider update and URI match look like?
Typical Content providers have a URI for each Table/View for a single row where _id is passed as a where_argument and a URI for multiple rows which uses where and where_arguments to select the rows to be updated.
Also it looks like you update by id. Android really want the id column named "_id", although I don't think is currently your issue, but it really depends on the URI it's using. Content Providers are usually coded with the _id and select by the column for a single row based on _id. That's why I want to see content provider. Your also selecting by the id yourself, this doesn't seem normal, although it could be accomplished, but not the norm. Typically the where part is something like 'colunm name = ?" and the next parameter where_arguments is a string array containing the value to replace the '?'.
Hope this helps.
I've come across a strange problem while writing an android app.
I've got a particularly messy piece of SQL (which I'm in the process of tidying) which returns a cursor for a custom listadapter.
The problem is part way through tweaking my code using SQLITEMAN I've found I'm getting correct results from SQLITEMAN (as I do some aggregation) but when I run it through android I get no results on a database that I copied directly from android using DDMS.
Again, yes I know the code is messy, but it does get results. If the code is actually the problem, it can be tidied up.
SELECT -1 as _id, 'player1|player2' as players, null as turntext, null as turnimage,30 as maxturns,19 as curturns
union
SELECT games._id,games.players,lastturn.turntext,lastturn.turnimage,games.maxturns,lastturn.curturns
FROM games
inner join (select _id,turntext,turnimage,t.gameid, tb.curturns from turns t inner join (select tb.gameid,count(tb._id) as curturns from turns tb group by tb.gameid) tb on tb.gameid = t.gameid where _id = (select max(_id)
from turns where gameid = t.gameid ) group by t.gameid) lastturn on lastturn.gameid = games._id order by games._id desc
EDIT: I've re-written the SQL so there are only 2 inner loops. Not surprisingly the issue still persisted.
After more investigation I've now got a new lead: when I was inserting the entries with the code below, I think the cast of the return value to int, while acceptable based on my methods, might have been stuffing up the submission of the values...
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_GAMEID,gameId);
initialValues.put(KEY_TURNTEXT,text);
initialValues.put(KEY_TURNIMAGE,imageBytes);
return (int)mDb.insert(TABLE_NAME, null, initialValues);
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.
In my search module I am using SQLite database. Sometimes I'm searching more than two values. So I am using AND condition and sometimes searching only one value. These two cases I need to implement in a single query. Please help me.
This is the query:
Cursor dbcur = myDB.rawQuery("select * from "+dbtable+" where Status='"+item+"'AND ball_court='"+ball+"'AND Tovendor='"+vendor+"'", null);
Sometimes I am searching status and ball_court, tovendor and sometimes I am searching status only. How to solve this problem?
Build the query string in stages, rather than all at once. If you're always going to select against the status, put that in the basic WHERE clause, then add any additional expressions. Use parameters (which you can do with SQLiteDatabase.query) rather than concatenating values into the query itself to prevent SQL injection. dbtable better not come from untrusted sources (e.g. users, the database itself). My Java's a little rusty, but try something like the following to start:
List<String> argList = new LinkedList<String>();
String selection = "Status=?";
argList.add(item);
if (ball != null && ball.length()) {
selection += " AND ball_court=?";
argList.add(ball);
}
if (vendor != null && vendor.length()) {
selection += " AND Tovendor=?";
argList.add(vendor);
}
String[] argArray = new String[argList.length()];
argList.toArray(argArray);
// columns is a String[] of column names
Cursor dbcur = myDB.query(false, dbtable, columns, selection, argArray, null, null, null);
Rather than appending strings, you might want to use a StringBuilder.
As for SELECT *, read "What is the reason not to use SELECT *?"
You might be able to get some answers if you post a sample query as well as what you might search for! I didn't totally understand your question, as I would/should be able to help out.