How to put String list in SQL database? - android

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.

Related

Android SQLite query string to reach to D in A~B~C~D~E~F where A,B,C,D,E and F could have any interested length and data

In an Android application,
In SQLite database, there is a column with the following data:
A~B~C~D~E~F
Where each of A,B,C,D,E and F could have variable length and data
For example,
A could be every possible interested name like Mike, Andy, Tom , ...
Or B could be any interested country name and so on
Now I need a Query to reach to D part, how?
FYI, '~' character is unique in the data (there would be just 5 characters of '~')
In other word, A,B,C,D,E,F don't contain '~'
Edit:
I need LIKE clause in a basic SQLite
I actually don't know of a way to do this using only the basic SQLite string functions. Therefore, I would suggest handling this from Java, after you have queried:
String input = "A~B~C~D~E~F";
String[] parts = input.split("~");
String target = parts.length >= 4 ? parts[3] : "";
Eureka! It's possible with LIKE clause (NOT LIKE) in a basic SQLite:
SELECT_QUERY =
String.format("SELECT * FROM %s WHERE %s NOT LIKE %s;",
Constants.TABLE_M4,
Constants.KEY_M4_Data,
"%~%~%~~%'"
);
If D is not empty, it is identified with the above query

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.

Does value get converted when inserted into database?

I was curious if androids SQLiteDatabase insert method automatically handles type conversion.
Here is my example:
I have a csv file with a column name of age. Its type will be an INTEGER.
Lets say I have already created the database and table.
Now I am parsing the csv file with CSVReader, which parses each line and inserts each value into an index of a String[].
In order to insert each line of data into the database, I have to use a ContentValue object, which allows me to store values in it.
//Parse each line and store in line...
ContentValue values = new ContentValue();
values.put(KEY_AGE, line[1]); // Assume line[1] is the age
database.insert(table, null, values);
If I store the age value as a string (as seen above), and then insert it into the table, does Android handle the conversion to INTEGER before inserting it into the database?
I am asking this because I am trying to insert a bunch of tables into a database, and it looks much cleaner when I can just iterate through an array then explicitly state each put call, i.e:
Also if anyone has any design suggestions feel free to tell me.
CLEAN
int i = 0;
for(String s : TransitContract.Routes.COLUMN_ARRAY) {
values.put(s, line[i]);
i++;
}
UGLY
values.put(TransitContract.Routes.KEY_ROUTE_ID, line[0]);
values.put(TransitContract.Routes.KEY_AGENCY_ID, line[1]);
values.put(TransitContract.Routes.KEY_SHORT_NAME, line[2]);
values.put(TransitContract.Routes.KEY_LONG_NAME, line[3]);
values.put(TransitContract.Routes.KEY_DESCRIPTION, line[4]);
values.put(TransitContract.Routes.KEY_ROUTE_TYPE, Integer.parseInt(line[5]));
values.put(TransitContract.Routes.KEY_URL, line[6]);
values.put(TransitContract.Routes.KEY_COLOR, line[7]);
values.put(TransitContract.Routes.KEY_TEXT_COLOR, line[8]);
return mDatabase.insert(TransitContract.Routes.TABLE_NAME, null, values);
When you declare a column as INTEGER, SQLite will automatically convert strings to numbers, if possible.
See the documentation for Type Affinity.
If your ContentProvider doesn't restrict it (i.e. pass it directly to the SQLiteDatabase.insert() method), it should work. SQLite is not that picky about the types used in queries/inserts and the actual column type.
However, it would be best practice to parse and check the values before inserting. Otherwise you might actually insert a string which can't be parsed as integer and therefore retrieving the value might fail.
References:
Boolean datatype accepting string value and integer value
SQLite table with integer column stores string

efficient insert in sqlite 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.

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