I am working on an application that stores everything in a database and it is accessed using a ContentProvider. My scenario is as follows:
I make a web call and receive a list of integers which represent the ids of the objects I need to retrieve from my database on the device.
I make a call to ContentResolver.query() with the following Selection:
Selection: _id=? OR _id=? OR _id=?
Selection Ids: 30; 165; 149;
So, I need to get all items where the id is either 30, 165, or 149. And I need them in that exact order.
This is the exact call I am making on the ContentResolver:
Cursor cursor = mActivity.getContentResolver().query(myUri, null, selection, selectionIds, null);
As you can see, I do not pass in any sorting. However, the result gives me a Cursor with the order being the following: 30, 149, 165. So, it appears it is defaulting the sorting by _id even though I do not specify any sort order. My question is, does anyone know of a way to stop this from happening?
When you select rows, from any database, without specifying an ORDER BY clause, you should consider the order of the results as undefined, i.e. it could come back in any order. The reason you are seeing it sorted by _id here is just due to circumstance - they are likely to be in that order on the underlying database files so that is the order SQLite reads them back in. However it is not safe to assume that will always be so.
So the actual answer to your question is no, you can't assume SQLite will return your rows in any particular order without an ORDER BY clause. If you are unable to provide such a clause (which appears to be the case here) you'll have to sort them in code after getting all the data from the cursor.
It is not defaulting to _id, it is giving you the records as they are in the db (which happen to be sorted by id). Pass your own sorting order if you don't want this.
Related
I am using this query
"select * from SomeTable group by SomeColumn"
It is returns list with accenting order, but i need to same order like in database.
For example the order in database is:
p
a
s
But result is:
a
i
p
Sample
The result need to be like distinct by CityEN but with all columns and order like 1.Paris 2.Amsterdam 3.Istanbul
In Sqlite, each row of a table has a unique rowid, which you can use for sorting.
select * from SomeTable group by SomeColumn order by rowid;
In your statement, add this line to sort the results:
order by min(rowid)
Your query does not enforce any order with ORDER BY clause so no assumption about row order should be made. If you want specific order add i.e. ORDER BY SomeColumn. See docs about all available order options: https://www.sqlite.org/lang_select.html#orderby
By the rules of SQL, you can't count on getting records back in any specific order without specifying an ORDER BY clause in your SQL query.
In practice servers sometimes return values in the order in which they're inserted, in the order of the first index created, or in the order of the primary key--but you can't count on this behavior, and in fact I've seen the behavior change between database maintenance windows or after the database version is upgraded. You definitely wouldn't want to count on a DB engine to give you back records in any particular order if you write a SELECT statement without an ORDER BY clause.
The only real way to get your records back in the order you inserted them is to create a timestamp column and then sort on it during the SELECT. If you don't want to worry about populating that column on INSERT, have that column auto-populate itself with a timestamp (depending on your DB engine).
i'm trying to find a good way to sort the search results according to relevance after performing a search with a SearchView in Android. For me relevance means the number of matches in two SQLite text columns
I'm using a CursorLoader and there the sort order can be given to the constructor at the end
CursorLoader tLoader = new CursorLoader(
getActivity(), ContentProviderM.ARTICLE_CONTENT_URI,
tProj, tSel, tSelArgs, SORT_ORDER);
(or set using the setSortOrder (String sortOrder) method)
But i need more flexibility than this because i'm looking to sort on the number of matches rather than just on one or two columns
The only solution i can see myself is to add another column in my SQLite table, do some processing, and supply that column as the sort column to the CursorLoader
Now for my question: What is the best way to supply the sort order information to the CursorLoader using SQLite syntax, avoiding having to add a new column? (And what could this SQLite code look like?) Also, i'd like to ask more in general: Is there a different solution to this problem that i've missed?
Grateful for any help! And with kind regards,
Tord
Depending on the content provider, if it just pass to the orderBy field, you can do anything.
SQLiteDatabase query
orderBy How to order the rows, formatted as an SQL ORDER BY clause
(excluding the ORDER BY itself). Passing null will use the default
sort order, which may be unordered.
you can do whatever you want, this is just the line after ORDER BY
P.S. It is totally depending on the Content Provider, it it choose to ignore the parameter, you can do nothing.
i found a "workaround" for this problem.
After investigating different ways to write sqlite code i ended up just adding a new table column just for sorting. This column simply stores an integer and is updated every time that the user performs a search, right before the CursorLoader is created
Advantages:
We can now do all of the relevance calculations in Java code
Drawbacks:
Relevance calculation is done as the search is done so if we have a large number of items it may take some time to process everything
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 got following problem, I need to use a Content Provider to read a
Database of an other App.
first I want all rows, and after analyzing the data only e.g. the rows
from _id = 1, 3 and 5.
how can I call a Content provider and select only these rows?
or is it possible to create a subset Cursor form an given Cursor?
Thanks in advance.
If you're talking to another app, I assume you're querying the other app's ContentProvider to get the data from them in the first place.
In this situation, the cleanest answer seems not to build your own ContentProvider that filters/wraps theirs. Instead query their ContentProvider from your application directly, and use the select clause in your query() to specify the conditions that define the subset of data you want to be given.
I get records from the system by quering a ContentResolver. I maintain the order of the items in the database. So I want to display the items in the order taken from my database.
How do I merge these two informations?
EDIT 1
I am looking after an alternative way now. As what I ideally want is:
get order of contacts by a custom order held in my database (this involves joining CR with my DB cursor, and doing an order by, later seams it's not possible with CursorJoiner)
but there is more, if the join is not unique I want to sort by contact's name as last measure
which is impossible using Cursor and Joiners, because of the missing feature of order bys, also I need to return a Cursor, as I will be using the in an ExpandableList
Also this translated to TSQL it would look like
select * from contactsdata
left join category on contactsdata.catid=category.id
order by category.pos asc, contact.display_name asc
So I am looking now after an alternative.
I have in mind to load in a temporary DB table all data from CR, then do the query on the temporary table where I can join tables and do order bys? How does this sound to you?
Take a look at CursorJoiner.
If that doesn't work, you can roll your own equivalent with a fair amount of pain, whiskey, or both.