Android: Retrieve data from sqlite Database - java

I currently I have my database set up like the following:
db.execSQL("CREATE TABLE " + DATABASE_TABLE + " (" + KEY_ROWID
+ " INTEGER PRIMARY KEY AUTOINCREMENT, " + KEY_LOCKERNUMBER
+ " TEXT NOT NULL, " + KEY_STATUS + " INTEGER, " + KEY_PIN
+ " INTEGER);");
And I am trying to write a method to get the pin code from the column for a specific locker number. Any ideas? I am very new I would like think I would need to use the query function and a cursor. I just one to get the integer value and store it into an int variable so I can compare the pin codes from what the user types in to the one in the database.

Queries to database returns in a Cursor object. You should use the db.query() method to get a row(s). Pass the table name, an array of columns you want to get (or null if you want all of them), pass a selection string that should be like "id = ?" or "key > ?", etc, then pass a String array containing the value for those ? inside the previous string,
and finally pass null for having, groupBy and orderBy unless you want to use them.
Cursor cursor = db.query(TABLE_NAME, new String[] { KEY_ROWID }, "id = ?", new String[] { Integer.toString(id) }, null, null, null);
After you get the Cursor, do cursor.moveToFirst() or cursor.moveToPosition(0) (can't remember the exact method, but the point is to move the cursor to the first retrieved row)
then you're going to iterate through the cursor with
while(cursor.moveToNext()) {
int keyRowIdColumnIndex = cursor.getColumnIndex(KEY_ROWID);
int yourValue = cursor.getInt(keyRowIdColumnIndex);
int keyLockNumberColumnIndex = cursor.getColumnIndex(KEY_LOCKNUMBER);
int pin = cursor.getInt(keyLockNumberColumnIndex);
}

This is a pretty straight forward task and there is a bunch of tutorials, examples, similar questions on SO:
How to perform an SQLite query within an Android application?
In general - you need to query the database passing your search arguments. See the documentation.
It will return you a Cursor with the matching results, which you can then iterate over and manipulate as you wish.
Fyi - storing password in a database table is a bad idea. On Android databases can be accessed and easily read. You either need to encrypt your data or think of another way to store it if it's important.

//Try This code
public String getLabeId(String LockNo)
{
ArrayList<String> Key_Pin_array = new ArrayList<String>();
Cursor cur = db.rawQuery("SELECT * FROM DATABASE_TABLE where KEY_LOCKERNUMBER = '" + LockNo + "'", null);
try {
while (cur.moveToNext())
{
System.out.println("Key_Pin" + cur.getString(3));
Key_Pin_array.add(cur.getString(3));
}
}
catch (Exception e)
{
System.out.println("error in getLabelID in DB() :" + e);
}
finally
{
cur.close();
}
return id;
}

Related

error occur when try to SELECT in sqlite android

so i recently learn to write a code in android using sqlite and i try to select data from sqlite but this error occur
ive tried some suggestion from the internet and read my book but i didnt solve my problem
public Penyakit getPenyakit1(String namaGejal){
SQLiteDatabase db = this.getReadableDatabase();
String query = "SELECT idPen FROM " + TABLE_CONTACTS + " WHERE " +
namapen + " =\"" + namaGejal + "\"";
Cursor cursor = db.rawQuery(query,null);
Penyakit penyakit = new Penyakit();
if(cursor.moveToFirst()){
cursor.moveToFirst();
penyakit.set_nomber(Integer.parseInt(cursor.getColumnName(0)));
penyakit.set_namaPen(cursor.getColumnName(1));
penyakit.set_idPenyakit(Integer.parseInt(cursor.getColumnName(2)));
penyakit.set_namGej(cursor.getColumnName(3));
penyakit.set_idGejala(Integer.parseInt(cursor.getColumnName(4)));
cursor.close();
} else {
penyakit=null;
}
return penyakit;
}
this is logcat
Process: com.example.lordbramasta.pakar, PID: 18914
java.lang.NumberFormatException: For input string: "idPen"
at java.lang.Integer.parseInt(Integer.java:615)
at java.lang.Integer.parseInt(Integer.java:650)
at com.example.lordbramasta.pakar.DBAdapter.getPenyakit1(DBAdapter.java:79)
i expected the value of idPen get selected , thank you
Your problem is this line:
penyakit.set_nomber(Integer.parseInt(cursor.getColumnName(0)));
cursor.getColumnName(0) returns idPen as this is the name of the only column returned by your query:
SELECT idPen FROM ....
and your code is trying to cast the string "idPen" to an integer.
So getColumnName() returns the name of the column at a specified index and not the value of the column.
You should do
penyakit.set_nomber(Integer.parseInt(cursor.getString(0)));
or if the data type of the column idPen is INTEGER then:
penyakit.set_nomber(cursor.getInt(0));
Also don't try to get any other columns because your query returns only 1.
Note: remove that cursor.moveToFirst(); inside the if block because it is already executed.
Probably you need to use a ' instead of ". So, change the query to the following:
String query = "SELECT idPen FROM " + TABLE_CONTACTS + " WHERE " +
namapen + " =\'" + namaGejal + "\'";
I'm suggesting you to use SQLiteDatabase.query() instead rawQuery like this:
// Define a projection that specifies which columns from the database
// you will actually use after this query.
String[] projection = {
"idPen"
};
// Filter results WHERE "namapen" = 'namaGejal'
String selection = "namapen" + " = ?";
String[] selectionArgs = { namaGejal };
// How you want the results sorted in the resulting Cursor
String sortOrder = null; // null for default order
Cursor cursor = db.query(
TABLE_CONTACTS, // The table to query
projection, // The array of columns to return (pass null to get all)
selection, // The columns for the WHERE clause
selectionArgs, // The values for the WHERE clause
null, // don't group the rows
null, // don't filter by row groups
sortOrder // The sort order
);
// do something with the cursor
Please take a look Read information from a database
If you want to get all columns data from your TABLE_CONTACTS use SELECT * FROM

Making calculation from SQLite

I am trying to do two SQLite tables, one to enter data and another one to retrieve the calculated data.
First I want to let the client enter some REAL data and then calculate in the background and put the new data to the textview.
For now, I tried to retrieve it from one table.
#Override
public void onCreate(SQLiteDatabase db) {
String sSQL;
sSQL = "CREATE TABLE " + DataContract.TABLE_NAME +
"(" +
DataContract.Columns._ID + " INTEGER PRIMARY KEY NOT NULL, " +
DataContract.Columns.PRODUCT_NAME + " TEXT, " +
DataContract.Columns.PRODUCT_WIDTH + " REAL, " +
DataContract.Columns.PRODUCT_LENGHT+ " REAL, " +
DataContract.Columns.PRODUCT_PRICE+ " REAL, " +
//This is the data I want to calculate and put to a textview in a
//new intent
DataContract.Columns.PRODUCT_TOTAL_PRICE + " REAL)";
Log.d(TAG,sSQL);
db.execSQL(sSQL);
}
I have a Serializable class and I tried to calculate the data in this class.
private final String ProductName;
private final double ProductLenght;
private final double ProductWidth;
private final double ProductPrice;
private final double ProductTotalPrice;
Then I tried to calculate the data in getter method.
public double getProductTotalPrice() {
return (getProductWidth() * getProductLenght() * getProductPrice())/1000;
}
However, I dont know how to put retrieve the calculated data back to the textview.
Should I create two tables or one table is enough for this operation ?
And also what is the easiest way to calculate data inside Java code and put it back to a column ?
Thank you !
And also what is the easiest way to calculate data inside Java code
and put it back to a column ?
To do nothing (i.e. calculate the value when extracting the data and reduce the amount of data stored in the database)
To add another column for the calculated value would be a waste as you can calculate the value when extracting the data (into the cursor) e.g. :-
Assuming the table (called myproducts) is populated as follows (note no PRODUCT_TOTAL_PRICE column as it's not needed) :-
Then extracting it using the query :-
SELECT
_ID,
PRODUCT_NAME,
PRODUCT_WIDTH,
PRODUCT_LENGTH,
PRODUCT_PRICE,
(PRODUCT_WIDTH * PRODUCT_LENGTH * PRODUCT_PRICE)/1000 AS CALCULATED_TOTAL_PRICE
FROM myproducts;
Will result in :-
You could have a method in your Database Helper such as :-
public double Cursor getTotalpriceBtId(long id) {
double rv = 0;
String column_name = "totalprice";
String calculation = "(" +
DataContract.Columns.PRODUCT_WIDTH + " * " +
DataContract.Columns.PRODUCT_LENGHT + " * " +
DataContract.Columns.PRODUCT_PRICE + ")/1000";
String[] columns = new String[]{calculation + " AS " + column_name};
String whereclause = DataContract.Columns._ID + "=?";
String[] whereargs = new String[]{String.valueOf(id)};
Cursor csr = this.getWritableDatabase().query(
DataContract.TABLE_NAME,
columns,
whereclause,
whereargs,
null,null,null
);
if (csr.moveToFirst) {
rv = csr.getDouble(csr.getColumnIndex(column_name));
}
csr.close();
return rv;
}
The underlying SQL is similar to the example above. However, just the one column is needed.
However, I dont know how to put retrieve the calculated data back to
the textview.
Something along the lines of :-
yourTextView.setText(String.valueOf(yourDBHelperInstance.getTotalpriceBtId(ID_OF_THE PRODUCT)));
or perhaps :-
yourTextView.setText(String.valueOf(yourproduct.getProductTotalPrice()));
No need to create two tables
after inserting the value into table you just create a function by below query
select sum(your column name) from yourtablename where condition on which basis you filter the data.

Cursor returns with no result after SQLite query (passes unit test but fails at run time) -- android

i have this method:
public Note getNoteById(long id) {
Cursor cursor = database.query(Config.NOTES_TABLE, Config.NOTES_COLUMNS, Config.ROW_ID+"="+id, null, null, null, Config.ROW_ID + " DESC");
//no match found
if(cursor.getCount() == 0)
return null;
cursor.moveToFirst();
Note result = new Note();
result.setId(cursor.getLong(cursor.getColumnIndex(Config.ROW_ID)));
result.setTitle(cursor.getString(cursor.getColumnIndex(Config.TITLE)));
result.setText(cursor.getString(cursor.getColumnIndex(Config.TEXT)));
result.setViewOrder(cursor.getLong(cursor.getColumnIndex(Config.VIEW_ORDER)));
result.setCreated(cursor.getString(cursor.getColumnIndex(Config.CREATED)));
result.createTagsFromString(cursor.getString(cursor.getColumnIndex(Config.TAGS)));
return result;
}
My problem is in the first few lines. The cursor at the beginning always returns with a count of 0 therefore making the function always returns null -- ONLY AT RUNTIME! -- i have written a test case for this method and it passes so i cant figure out why it would only fail at runtime?
heres the relevant part of the test case. i basically insert new data to the table and try to get it back by its id and compare attributes to confirm its the same:
#Test
public void testGetNoteByIdMatch(){
testTable.load();
Assert.assertEquals(0, testTable.getAllNotes().getCount());
testTable.newEntry(note1);
testTable.newEntry(note2);
Cursor cursor = testTable.getAllNotes();
Assert.assertEquals(2, testTable.getAllNotes().getCount());
cursor.moveToFirst();
Note result = new Note();
result.setId(cursor.getLong(cursor.getColumnIndex(Config.ROW_ID)));
result.setTitle(cursor.getString(cursor.getColumnIndex(Config.TITLE)));
result.setText(cursor.getString(cursor.getColumnIndex(Config.TEXT)));
Note checker = testTable.getNoteById(result.getId());
Assert.assertEquals(result.getId(), checker.getId());
Assert.assertEquals(result.getTitle(), checker.getTitle());
//move and try another search
cursor.moveToNext();
result = new Note();
result.setId(cursor.getLong(cursor.getColumnIndex(Config.ROW_ID)));
result.setTitle(cursor.getString(cursor.getColumnIndex(Config.TITLE)));
result.setText(cursor.getString(cursor.getColumnIndex(Config.TEXT)));
checker = testTable.getNoteById(result.getId());
Assert.assertEquals(result.getId(), checker.getId());
Assert.assertEquals(result.getTitle(), checker.getTitle());
}
this is the table structure in the onCreate method for the database:
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + Config.NOTES_TABLE + " (" +
Config.ROW_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
Config.TITLE + " TEXT NOT NULL, " +
Config.TEXT + " TEXT NOT NULL, " +
Config.CREATED + " TEXT NOT NULL, " +
Config.VIEW_ORDER + " INTEGER NOT NULL, " +
Config.TAGS + " TEXT NOT NULL)"
);
}
Your test checks that the values can be read out in the same order they were inserted, but does not actually verify the data is going in as expected. It's possible that the result and checker objects both have null values for all properties. Verify that the object properties have the expected values once read out of the db.

Getting Contacts based on the GroupID in Android

I'm having kind of a problem here, since I just startet developing for Android. I downloaded the sample from the official Android website "http://developer.android.com/training/contacts-provider/retrieve-names.html", which is basically capable of retrieving an showing all the contacts from the phone. The feature I wanted to add is to just show contacts from a certain group like "Friends" (hardcoded).
As far as I narrowed it down I have to change the selection part
final static String SELECTION =
(Utils.hasHoneycomb() ? Contacts.DISPLAY_NAME_PRIMARY : Contacts.DISPLAY_NAME) +
"<>''" + " AND " + Contacts.IN_VISIBLE_GROUP + "=1";
to something like this
final static String SELECTION =
Contacts.GroupID = "Friends";
which gives me errors, because it can't find the column.
I'm very eager to explore the potential of Android, but that one is giving me headache.
There two ways for getting list of contacts of a group. First, I suppose you have GroupId and want to get related list of contacts.
String[] projection = {
ContactsContract.Groups._ID,
ContactsContract.Groups.TITLE,
ContactsContract.Groups.ACCOUNT_NAME,
ContactsContract.Groups.ACCOUNT_TYPE
};
return context.getContentResolver().query(
ContactsContract.Groups.CONTENT_URI, projection, ContactsContract.Groups._ID + "=" + groupId , null, null
);
Second way:
I suppose you want to get contacts of specific group by a constants name. so, it's enough you change above codes:
context.getContentResolver().query(
ContactsContract.Groups.CONTENT_URI, projection, ContactsContract.Groups.ACCOUNT_NAME + "='Friends'" , null, null
);
Now you have necessary details from specific Group. Then you can fetch list of Contact List:
public static Cursor getContactsOfGroup(Group group) {
// getting ids of contacts that are in this specific group
String where = ContactsContract.CommonDataKinds.GroupMembership.GROUP_ROW_ID + "="
+ group.id + " AND "
+ ContactsContract.CommonDataKinds.GroupMembership.MIMETYPE + "='"
+ ContactsContract.CommonDataKinds.GroupMembership.CONTENT_ITEM_TYPE + "'";
Cursor query = context.getContentResolver().query(
ContactsContract.Data.CONTENT_URI,
new String[] {
ContactsContract.CommonDataKinds.GroupMembership.CONTACT_ID
}, where, null, ContactsContract.Data.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
String ids = "";
for (query.moveToFirst(); !query.isAfterLast(); query.moveToNext()) {
ids += "," + query.getString(0);
}
if (ids.length() > 0) {
ids = ids.substring(1);
}
// getting all of information of contacts. it fetches all of number from every one
String[] projection = new String[]{
"_id",
"contact_id",
"lookup",
"display_name",
"data1",
"photo_id",
"data2", // number type: 1:home, 2:mobile, 3: work, else : other
};
String selection = "mimetype ='" + ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE + "'"
+ " AND account_name='" + group.accountName + "' AND account_type='" + group.accountType + "'"
+ " AND contact_id in (" + ids + ")";
return context.getContentResolver().query(BASE_URI, projection, selection, null, null);
}
Notice, in second fetch in this method we check accountName and accountType to be sure this record is related this group, because may be there are some records that stored for another Apps like WhatsApp. and we don't like get those. ok?
I hope will useful for you.

sqlite how to add value on conflict

I have a database with product name,product price and product counter.
Product name is unique,product price gets replaced everytime a new value is entered and the problem is the product counter.
Its default value is 1,when a new product is entered his value is set to 1.I need it to increment whenever there is a conflict for the product name.So if Cheese is entered twice,the counter will say 2 and so on.
What i need it to do is when there is a conflict,add 1 to its value. I want to do it this way because i'll need this later.I'll need to add the inputed value to the table value on some other thing i plan to implement in my app.
How can i achieve this ? I'd like to keep doing it the way i'm doing it now,with the contentvalues method of inserting and not with the sqlite syntax(INSERT,SELECT,etc).Is that even possible ? Cuz i'm an absolute 0 at sqlite syntax.And also,i need it to have a method that i can call in other activities to insert into the database (like insertCountry(Japan,10))
public class SQLiteCountryAssistant extends SQLiteOpenHelper {
private static final String DB_NAME = "usingsqlite.db";
private static final int DB_VERSION_NUMBER = 1;
private static final String DB_TABLE_NAME = "countries";
private static final String DB_COLUMN_1_NAME = "country_name";
private static final String DB_COLUMN_2_NAME = "country_price";
private static final String DB_COLUMN_3_NAME = "country_counter";
private static final String DB_CREATE_SCRIPT = "create table "
+ DB_TABLE_NAME
+ " (_id integer primary key autoincrement, country_name text UNIQUE ON CONFLICT REPLACE,country_price text,country_counter integer default '1' );)";
And this is how i insert :
public void insertCountry(String countryName, String countryPrice) {
sqliteDBInstance.execSQL("INSERT INTO " + DB_TABLE_NAME
+ "(country_name, country_price) VALUES('" + countryName
+ "', '" + countryPrice + "')");
}
Incrementing a value to a specific cell is not available in sqlite. You have to read the current value of cell and add your needed value to it and replace it with the old one. You can use update method.
public void update(String countryName, String price, long id) {
ContentValues cv = new ContentValues();
cv.put(dbHelper.COLUMN_1, countryName); // These Fields should be your
// String values of actual column
// names
cv.put(dbHelper.COLUMN_2, price);
database.update(dbHelper.TABLE_NAME, cv, "_id " + "=" + id, null);
}
every time you're going to add a row to your table you have to read all it and check if the row exists.here is a method to retrieve all rows:
public List<TableRow> getAllRows() {
List<TableRow> rows= new ArrayList<TableRow>();
Cursor cursor = database.query(Helper.TABLE_SITUPS, allColumns,
null, null, null, null, null);
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
TableRow row = cursorToRow(cursor);
comments.add(row);
cursor.moveToNext();
}
// Make sure to close the cursor
cursor.close();
return rows;
}
TableRow is a class for database table rows and contains fields stands for actual table columns.
with iterating this list and get "country" value of each one you can understand if that row exists or not.
These are basic concepts of sqlite databases programming. I recommend you to research a bit in this matter.
I don't know your database class, but check this method:
return this.sqliteDBInstance.insertWithOnConflict(DB_TABLE_NAME, null, contentValues, SQLiteDatabase.CONFLICT_REPLACE);
If you are creating your column correctly, if there is a conflict, the new entry will replace the old one.
EDIT: after your last comment, all you need is an update: first query your database with the name of your item (check carefully if parameters are ok):
return this.sqliteDBInstance.query(DB_TABLE_NAME, null, DB_COLUMN_1_NAME + "=?", new String[] {productName}, null, null, null);
This will return a Cursor with 0 or 1 row. If there aren't row, you can proceed inserting data normally (don't forget to add your counter: is 1 on first insert):
public void insertCountry(String countryName, String countryPrice) {
sqliteDBInstance.execSQL("INSERT INTO " + DB_TABLE_NAME
+ "(country_name, country_price) VALUES('" + countryName
+ "', '" + countryPrice + "', '" + countryCounter + "')");
}
if there is 1 row, your product is already on your database, so just iterate the Cursor, take the value on counter, add +1 on it and update your database with this method:
public int update (String table, ContentValues values, String whereClause, String[] whereArgs)

Categories