Any help me? I want to display random data from SQliteDB to multi TextView, thanks!
protected void setQuestionView(){
txta.setText(currentQ.getOptOne());
txtb.setText(currentQ.getOptTwo());
txtc.setText(currentQ.getOptThree());
txtd.setText(currentQ.getOptFour());
Assuming that you've extracted the data as a cursor, you could get the number of rows using int randomrange = (cursor.getCount()) -1; (obviously if range is less than 0 then there are no rows).
Once you have obtained the random number as an integer, then you can use cursor.moveToPosition(randomposition) to move the cursor. You can then do txta.setText(cursor.getString(columnoffset)); or if you wish to use the column's name then you could use txta.settext(cursor.getString(cursor.getColumnIndex(columnasstring)));
You could then repeat this 4 times. However, you have a chance to have the same text values.
An alternative way is to have the cursor extract the required number of random rows e.g. base the query on the following SQL :-
SELECT * FROM yourtable ORDER BY RANDOM() LIMIT 4;
Related
I fetch records in my SQLite database like this.
spellId = extra.getString("spellId");
DBase db = new DBase(this);
db.open();
String[] data = db.getRecord(Integer.parseInt(spellId));
db.close();
Can I get random data like this without using raw queries and cursor?
try like this:
db.rawQuery("SELECT * FROM mainTable ORDER BY RANDOM() LIMIT 1", null);
You can use Random#nextInt() like
String[] data = db.getRecord(new Random().nextInt(num));
where num falls in the range of your record IDs. You would need to adapt this solution in case your Ids are fragmented and do not form a consecutive range.
One of the ways to do that would be to first create a query to fetch all the primary keys and store the values in a set somewhere. Then pick a random key by generating an index using Random.
String[] data = db.getRecord(IDSet.get(new Random().nextInt(IDSet.size())));
Check out the docs for more information.
Returns a pseudorandom, uniformly distributed int value between 0 (inclusive) and the specified value (exclusive), drawn from this random number generator's sequence.
If you're considering a DB query solution
A better alternative to using ORDER BY RANDOM() (which is known to not scale well as the number of rows in your table grows) is to let SQLite return a random row using an OFFSET.
First save the total number of rows num somewhere.
SELECT COUNT(*) AS num FROM spells;
Then choose a random number rnum between (0, num) using Random and use the query
SELECT * FROM spells LIMIT 1 OFFSET rnum;
I'm working to develop an application that has to query at some time, a database with over 4k rows, and each row has 90 fields (Strings). The problem is that if I select * from database, my cursor gets really big (over 4MB). And the cursor in android is limited to 1MB.
How can I solve this, or what's the most elegant method to workaround this?
It is possible to split database in smaller chunks and query them out?
I found a way to handle this and I want to share with all who need it.
int limit = 0;
while (limit + 100 < numberOfRows) {
//Compose the statement
String statement = "SELECT * FROM Table ORDER someField LIMIT '"+ limit+"', 100";
//Execute the query
Cursor cursor = myDataBase.rawQuery(statement, null);
while (cursor.moveToNext()) {
Product product = new Product();
product.setAllValuesFromCursor(cursor);
productsArrayList.add(product);
}
cursor.close();
limit += 100;
}
//Compose the statement
String statement = "SELECT * FROM Table ORDER someField LIMIT '"+ (numberOfRows - limit)+"', 100";
//Execute the query
Cursor cursor = myDataBase.rawQuery(statement, null);
while (cursor.moveToNext()) {
Product product = new Product();
product.setAllValuesFromCursor(cursor);
productsArrayList.add(product);
}
cursor.close();
The main idea is to split your data, so you can use the cursor as it should be used. It's working under 2 s for 5k rows if you have indexed table.
Thanks,
Arkde
Well as a rule you never do select *. For a start each row will have a unique identifier, and your user will want to select only certain rows and columns - ie what they can see on an android screen. Without appearing to be rude this is a pretty basic question. You only return the columns and rows you want to display for that screen on the phone - otherwise you consume unnecssary battery life transfering never to be diaplayed data. the standard approach is to used parameterised stored procedures. Google parameterised stored procedures and do a little reading - by the by - you cant update any table unlees you return the unique row identifier for that table.
Do you need all these rows at the same time? Can you fetch them in parts? This question has been asked several times: Android SQLite and huge data sets
Here's one more suggestion: If you have 90 fields that you need to modify, split them into 10 different views. On each view have a left arrow and right arrow so you can horizontally traverse across screens. Hence each view will show 9 fields. Or some strategy like that. Essentially these are all the same views except for column names so you shouldn't have to modify much code.
I have trouble putting together a delete statement in my Android application (I am using OrmLite).
I have a table filled with records. Two of the fields are "dateCreated" (type Date) and "imageSize" (type int). In my code I have a method free(int size). This method tells me that I have to delete oldest records from my table that sum "imageSize" <= size.
For instance .. i get parameter 1000. Each record has value lets say 100. That means i have to delete 10 of the oldest records.
Can some one please provide me with optimal raw SQL statement or even better an OrmLite code for this?
I would be most gratefull.
Unfortunately, you can't do this with a single SQL statement. There is no way to say
select records until their sum is less than X
You could doing multiple queries until you found the oldest records whose sum is less than X but it would take a number of separate SQL calls.
I'd recommend selecting the last X images with their sizes and then doing a delete of the right number of images using a DELETE ... IN .... Here's the pseudo code:
while (true) {
SELECT id, imageSize FROM yourtable ORDER BY dateCreated DESC LIMIT 10;
find the images from the bottom whose sum(imageSize) <= parameter
delete the found images
break if you exceed the parameter otherwise loop and get the next 10
}
try this,
DELETE FROM yourtable WHERE imageSize <= (SELECT SUM(ImageSize) FROM yourtable)
Use the same parameter for your function
I have created a database and all works fine. But How I can get out last five rows, which one's column value is for example 1.
The select and insert function have synchronized function, so the reading and inserting doesn't happen same time. There has more than 300 hundreds rows, but I only need get cursor object last 5 rows (so I get all columns in one row) which one's column value is 1.
Thanks for any helps!
SELECT * -- list of the columns you want
FROM table
WHERE column1 = 1 -- rows with column1 = 1
ORDER BY (ordering columns) -- columns by which you want to order
LIMIT 5 -- and get the last 5
I think you want to select the first five rows which have all have a certain column with a value of one. If so, using a WHERE and LIMIT statement should help:
SELECT * FROM tbl WHERE the_column = 1 LIMIT 5
You can Use the method database.query();
as follows:
Cursor cursor = database.query(false, TABLE,new String[] {COLUMNS_TO_SELECT},"YOUR_WHERE_CLAUSE", null, null, null, null /*ORDER BY*/, "5"/*YOUR_LIMIT*/);
Have a look at Documentation
I've been looking at the notepad tutorial from the android developer site, I'm sorta stuck with two areas - can anyone help?
Firstly the tutorial creates a db with 3 columns: id, title and body. I would like to change the body to a decimal value. Secondly I need to total this column with the decimal value.
So where I have the EditText for the body column is it correct to set the input type to "numberDecimal" in the layout xml? Are any other changes necessary?
How do I then total these the values in this column, should I use be using some sort of loop to go through each record in that column and add them together?
Such as:
int total = 0;
for(int i = 0; i < mydb.table.NumberOfRows; i++) {
total = total + mydb.table.body[i]
}
* apologies I don't even know if a function to count the number of rows exists or how to access a particular part of a table (i suck at SQL and haven't been around java for a while)
Advice would be great!
Just changing the input mode of the EditText view to "numberDecimal" is not enough, but it's a good start, so you can be sure, that you user cannot input any non decimal characters.
To change the data type of the body column, you got to adapt the create statement that is used to create the table. Change the data type from TEXT to REAL so the body column can store float values.
Furthermore you got to adapt the insert statement as the body column is not a TEXT column any longer. So you got to convert the string from the EditText view which represents you numeric value to float before you pass it to the insert statement.
To sum up the all body values, you don't need a loop, you can let the db do this for you using the sum() or total() aggregation function (depending on you needs). The statement will look something like this.
SELECT sum/total(body) FROM <table name>
Replace <table name> with the name of the table.
apologies I don't even know if a function to count the number of rows
exists or how to access a particular
part of a table (i suck at SQL and
haven't been around java for a while)
To loop over the results of a database query you don't need to know how many rows the result has. As a result of a query you get a Cursor object which references the rows returned by the query. To loop over these rows you can use the following statement:
Cursor cursor = queryDB(.......)
while(cursor.moveToNext()){
<do something with the current result row>
}
The fact that you are using the Notepad example as the basis of what your doing, I am correct in assuming that you're using a ContentProvider? Ok so what you have to do is run a query that retrieves ALL the entries in the database:
Cursor c = managedQuery(Notes.CONTENT_URI, new String[] { Notes.BODY }, null, null, null);
Then as you were saying, loop through the cursor:
if (c.moveToFirst()) {
long total = 0;
long body;
int bodyColumn = c.getColumnIndex(Notes.BODY);
do {
// Get the field values
body = c.getLong(bodyColumn);
phoneNumber = cur.getString(phoneColumn);
total += body;
} while (cur.moveToNext());
Does that answer your question? Comment if you need anything specified.
I am working on an answer to a similar question at the moment. I currently thinking that the life of the database would cause a looped tallying method to become very annoying so if I were you I would design the database to keep the tally for you and keep the total input rows. It's just a suggestion but I think it is easier to do two very simple one line methods than one continuously growing recursive/looped method.