efficient insert in sqlite android - android

Does anyone know a more efficient way of inserting a row into sqlite?
I am worried of split function.
Should I store the values in xml or json?
If you have any proposals, I would like to know.
my array of values is
private static final String[] inShopCategories =
{"Babies;5;#drawable/ic_launcher",
"Fruit / Vegetables;3;#drawable/ic_launcher",
"Meat / Fisth;2;#drawable/ic_launcher"};
and my code is:
public void onCreate(SQLiteDatabase db){
//create table
db.execSQL(cShopCateg);
//insert default shopping categories with InsertHelper
InsertHelper ih = new InsertHelper(db, tShopCateg);
final int nameCol = ih.getColumnIndex(KEY_NAME);
final int priorityCol = ih.getColumnIndex(KEY_PRIORITY);
final int iconCol = ih.getColumnIndex(KEY_ICON);
for(int i=-1,l=inShopCategories.length; ++i<l;){
ih.prepareForInsert();
String[] s = inShopCategories[i].split(";");
ih.bind(nameCol, s[0]);
ih.bind(priorityCol, s[1]);
ih.bind(iconCol, s[2]);
ih.execute();
}
}

do anyone know a more efficient way of inserting row in sqlite?
Yes.
i am worried of split function
That makes sense. You are wasting CPU cycles for no good reason.
should i store the values in xml or json?
Those would waste more CPU cycles for no good reason.
if you have any proposals, i would like to know.
Option #1: Get rid of all this code and pre-package your database, with its data already inserted, with your app, using something like SQLiteAssetHelper.
Option #2: Have your String[] be full SQL INSERT statements and execute those, rather than going through a lot of parsing and concatenating to reach the same end.
Option #3: If somebody is pointing a gun at your head to use InsertHelper, have a two-dimensional String array (String[][]) for your rows and columns.

Related

Possible to use ContentValues.put to update one column as sum of others

Is it possible to use ContentValues.put() to update a column in a SQLiteDatabse to be the sum of other columns?
I have searched on here and on the web and the closest answer I have found is: Update one column as sum of other two columns. This doesn't quite answer my question because it requires a raw database command, which I would prefer to avoid (if possible).
I have a fairly static database that I have generated unique permutations in (long setup, fast queries). I am attempting to set a total column at the end for even faster sorting on the permutations. I am currently attempting to use:
ContentValues values = new ContentValues();
values.put(totalVal, sumString);
where I have tried to set sumString to both:
=val_1+val_2+val_3...
and
val_1+val_2+val3...
When I look at my database in adb shell, sqlite3 I see:
Which looks... correct? Except when I query my database after this has been set, I get this in the log:
My val_* columns show values in the same adb shell, sqlite3 dump. Also, I do not set the totalVal column to this sumString until the val_* columns are all populated with their values.
Is it just not possible to use ContentValues.put()? Does it do some sort of internal escaping?
The reason it seems like it should work to me is the totalVal column is set to REAL so if ContentValues.put() does do internal escaping I thought I would get an error since I would essentially be putting a String value in a column that should only accept REAL.
Like I said earlier, my database is pretty static and only there for fast queries and sorting. It would be possible for me to loop through all the val_* columns and manually sum them up. Although, there are thousands of rows in my database so I was hoping to avoid this and was looking for a more elegant way to do this.
Thanks for the help.
SQLiteDatabase.update() is just a convenience method for updating rows in the database, so in your case you are just overcomplicating things trying to use ContentValues instead of SQLiteStatement and binding arguments which is what SQLiteDatabase.update() uses internally but preventing that column names were considered Strings.
It's not very clear from your example but if you are trying to update some values and at the same time calculate the totalVal do something like this
SQLiteStatement stmt = db.compileStatement("UPDATE mytable SET val_1=?, val_2=?, val_3=?, totalVal=val_1+val_2+val_3 WHERE expr");
stmt.bindLong(1, 1);
stmt.bindLong(2, 3);
stmt.bindLong(3, 5);
stmt.executeUpdateDelete();
EDIT
So as mentioned in your comment you don't need to bind values, it's even simpler
final int rows = db.compileStatement("UPDATE mytable SET totalVal=val_1+val_2+val_3").executeUpdateDelete();
and regarding your comment about "raw" SQL, ContentValues are not an option so this is the only way (AFAIK).

How to retrieve data from multiple Parse.com Tables/Classes

I have two tables (Classes):
StudentInformation: with columns RollNumber, address, name, school
StudentMarks : with columns RollNumber, Marks1, Marks2, Marks3
I've been able to save the data from a single form into these two simultaneously, but not getting a clue on how to put a query while retrieving into a listview or any other view something like
'return rows (from both tables together) where roll number = 1234' / 'return rows (from both tables together) where Marks2 > 50'
I'm using Parse.com backend for Android
Kindly help
Thanks
First, the UI aspect of showing in a ListView is provided by ParseQueryAdapter. https://parse.com/docs/android_guide#ui-queryadapter
Regarding the query, I do not think you can join tables in the way you want. Instead, you could create a pointer in StudentMarks to StudentInformation.
Then you can query something like:
ParseQuery<ParseObject> query = ParseQuery.getQuery("StudentMarks");
query.include('studentInformation'); // include the pointer to get StudentInformation
query.whereEqualTo("RollNumber", 1234);
query.whereGreaterThan("Marks2", 50);
... // perform query
In the results StudentInformation will be available like this:
List<ParseObject> objects; // the result from the query
ParseObject studentMark = objects.get(0); // example using first object
ParseObject studentInformation = studentMark.get("studentInformation");
String studentName = studentInformation.get("name");
String studentAddress = studentInformation.get("address");
... // etc
Alternatively you could also store a Relation of StudentMarks on StudentInformation, just to let you know that this is also an option, though I do not feel like it fits your current need as well as the solution presented above.

What is the most efficient way to convert String numbers to Integers in SQLite, in order to sort by highest value?

I have two columns in my SQLite Database, name and score. I need to display the out put of all table records by score descending from highest value. I have this working at the moment but due to score being a String, of course it only goes by the first number in the string, so 30 is above 200 etc...
Here is my SQL code:
private static final String fields[] = { "name", "score", BaseColumns._ID };
Cursor data = database.query("scores", fields, null, null, null, null, "score DESC");
I have no idea how I can continue to use the above code as well as converting all of the score values to integers in order to sort by highest score first. I started to do this by converting each score value into an integer and store it in an array in order to sort them, but then I only have half of my information, so this was a bad idea, I had not thought through.
I spent about an hour reading the SQLite documentation in order to seek some way of doing this more efficiently as well as scour Stackoverflow, but to no avail. Can anyone provide advice on how I should proceed to do this?
This answer solves the problem by casting the strings as integers in the query. This is better than doing it in the program because the database is built for storing and sequencing large amounts of data, so it is much more efficient to change the query than the code.
I think the right answer is to store them as their correct type, since you only do that once when you INSERT. Why reformat every time you query and display? Makes no sense to me.

How to put String list in SQL database?

I have an edittext that allows the user to enter in numbers up to 10.
I want to be able to save this numbers to a SQLite database as a String list.
Does SQL allow this to be done? If so how?
Such as
String [] list = {1020300303,1020303001,0102003020};
You can do it, but you'll be breaking normalization rules.
If you persist that array as a single string (comma-delimited?), you'll have to parse it to look at individual values. Not a good idea.
A normalized schema would use a one-to-many relationship between two tables. One would be the parent, the other the child with one row per value and a primary/foreign key relationship. You'd get the values back using a JOIN.
If you're so intent on doing this, you'll have to concatenate all the Strings in the array into one, with some delimiter in between them that you're sure will never appear in any of the Strings you're combining. Once you have a single delimited String, INSERT it into a String-type column in a table in your SQLite database.
Since you insist on seeing some code, here's what it might look like in Java:
String [] list = { "1020300303", "1020303001", "0102003020" };
StringBuilder concatenatedList = new StringBuilder();
for (String s : list) {
concatenatedList.append(s).append('~'); // Any delimiter will do.
}
PreparedStatement ps = connection.prepareStatement("INSERT INTO MySQLiteTable(stringColumnName) VALUES(?)";
ps.setString(1, concatenatedList.toString());
int numRowsAffected = ps.executeUpdate();
I wouldn't write it this way - no cleanup, no error handling, no good encapsulation. But it shows where you want to go.

Android SQL - Notepad Tutorial

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.

Categories

Resources