Java.lang.outofmemory error while performing sqlite database operation - android

After storing data into sqlite database i need to retrieving that data and display.
so for that i did like this.
private void display() {
// TODO Auto-generated method stub
try{
cursor2=database.query("patienttestdetails", new String[]{"date","sugarlevel"}, "pid="+patientId+"", null, null, null, "ptdid desc", "2");
if(cursor2.getCount()==0)
Toast.makeText(BloodsugarActivity.this, "Add Your Bloodsugar Details To See Here", Toast.LENGTH_LONG).show();
else
{
while(cursor2.moveToFirst())
{
bloodsugardetails=new TextView(this);
bloodsugardetails.setText(cursor2.getString(cursor2.getColumnIndex("date"))+" "+cursor2.getString(cursor2.getColumnIndex("sugarlevel")));
bloodsugardetails.setTextSize(20);
bloodsugardetails.setBackgroundResource(R.drawable.gray_view);
bloodsugardetails.setGravity(Gravity.FILL_HORIZONTAL);
layout.addView(bloodsugardetails);
}
}
cursor2.close();
database.close();
}
catch(Exception exception)
{}
}
My date base query is like this:
database.execSQL("create table if not exists patienttestdetails(ptdid integer primary key autoincrement,pid integer,date text,sugarlevel interger, FOREIGN KEY(pid) REFERENCES patientdetails(id))");
My database inserting is fine i checked the database. But while display, i am getting Java.lang.outofmemory error. My application have lot of XML files and lot of database operations. Before that all are fine i don't know why i am getting this error?
Logcat details:
https://docs.google.com/file/d/0B_c-SDSO63obZUdicVdDRWlKWXc/edit?usp=sharing
All advices are accepted
Thank you
SHANKAR

You have an infinite loop there. Cursor.moveToFirst returns true if cursor has records (and yours apparently does).
http://developer.android.com/reference/android/database/Cursor.html
Change it to moveToNext()
EDIT: On a side note, doing DB access and UI update in the same thread (UI thread) is not recommended.

Related

About SQLite 3, is it required to read after write?

In an Android application, concerning SQLITE3,
Is it required to read after write or we can just count on a successful transaction ?
Update to show the function to insert data:
// Insert a post into the database
public void addM0(Store_M0_DataClass mStore_M0_DataClass)
{
// Create and/or open the database for writing
SQLiteDatabase db = getWritableDatabase();
// It's a good idea to wrap our insert in a transaction. This helps with performance and ensures
// consistency of the database.
db.beginTransaction();
try
{
// The user might already exist in the database (i.e. the same user created multiple posts).
ContentValues values = new ContentValues();
values.put(KEY_M0_ID, mStore_M0_DataClass.getM0_ID());
values.put(KEY_M0_IMAGE1, mStore_M0_DataClass.getM0_Image1());
values.put(KEY_M0_IMAGE2, mStore_M0_DataClass.getM0_Image2());
values.put(KEY_M0_ENABLE, mStore_M0_DataClass.getM0_Enable());
db.insertOrThrow(TABLE_M0, null, values);
db.setTransactionSuccessful();
}
catch (Exception e)
{
}
finally
{
db.endTransaction();
}
}
An insert or any single action is automatically enclosed in a transaction, as such there is no benefit in wrapping it in a transaction. However, if you were doing multiple inserts in a loop then beginning a transaction prior to the loop, setting it as successful, if successful, after the loop, and ending the transaction after the loop it would have a benefit.
There is also little need to use insertOrThrow unless you want to trap an exception, as the insert method is effectively INSERT OR IGNORE and the result is the rowid of the inserted row, which will be 1 or greater (in most normal use cases).
rowid is a special, normally hidden column, frequently aliased using by using a column defined using specifically column_name INTEGER PRIMARY KEY or column_name INTEGER PRIMARY KEY AUTOINCREMENT Rowid Tables
(noting that AUTOINCREMENT is generally not required and has overheads) SQLite Autoincrement
As such using :-
public long addM0(Store_M0_DataClass mStore_M0_DataClass)
{
// Create and/or open the database for writing
SQLiteDatabase db = getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_M0_ID, mStore_M0_DataClass.getM0_ID());
values.put(KEY_M0_IMAGE1, mStore_M0_DataClass.getM0_Image1());
values.put(KEY_M0_IMAGE2, mStore_M0_DataClass.getM0_Image2());
values.put(KEY_M0_ENABLE, mStore_M0_DataClass.getM0_Enable());
return db.insert(TABLE_M0, null, values);
}
However, if you wanted to store multiple Store_M0_DataClass objects then you could have :-
public int addManyMo(Store_M0_DataClass[] mStore_M0_DataClasses) {
int rv = 0;
SQLiteDatabase db = this.getWritableDatabase();
db.beginTransaction();// <<<<<<<<<< wrap all inserts in a transaction
for (Store_M0_DataClass m0: mStore_M0_DataClasses) {
if(addM0(m0) > 0) {
rv++;
}
}
// Assumes OK if any inserts have worked, not if none have worked
if (rv > 0) {
db.setTransactionSuccessful();
}
db.endTransaction();
return rv; // Retruns the number of rows inserted
}
As for :-
Is it required to read after write or we can just count on a
successful transaction ?
A transaction being successful commits what was in the transaction. Comitting is effectively writing the data to disk so there is no need to do anything after a commit.
with WAL (Write Ahead logging) the data is written to the WAL file rather than the database (and also the shm file). However when accessing the database if the WAL has data it is effectively read as being part of the database. The WAL data is written to the database when the WAL is checkpionted.

Update query not updating the column using SQLite on Android

In my app, when the activity is destroyed, I want to update a column value to 0. For that I have written the query, but it seems not to be working for me, because when ever I start the app I get the same old values.
Code
public void resetSelectOptions() {
database = DatabaseManager.getInstance().openDatabase();
String query = "Update " + TableName + " SET " + Selected_Option + "=0";
try {
database.rawQuery(query, null);
}
catch (SQLiteException e) {
}
DatabaseManager.getInstance().closeDatabase();
}
How can I fix this problem?
Use this method to updating the rows,database.update() and
rawQuery is used to select query.
rawQuery() only executes queries (SELECT).
For any other SQL command, use execSQL().
So, simply convert this
database.rawQuery(query, null);
to this
database.execSQL(query, null);
It is not correct that the rawQuery() method executes only SELECT queries, it doesn't, but it is unnecessary to use it for an update, because you don't have any result - what to be iterated with the result Cursor at the ends, so try to use the execSQL() method. For more information take a look at this SO question android.database.sqlite.SQLiteDatabase.rawQuery() is not updating a DATETIME column with a SQLite datetime() function

How create table behaves in transactions?

I run two transactions.
In first transaction the table test is created,
but then I say rollback for this transaction.
I think that then the table test should have been created or not,
but not something between.
Then I run the other transaction to test what has happened:
I insert one row in the table test.
That seems work in program but when I go to sqlite prompt,
I do not see the table test there when I say the command ".schema".
Can someone tell what is happening?
Output of my code is:
"Insert ok."
try
{
db.beginTransaction();
String s =
"CREATE TABLE test(id INTEGER PRIMARY KEY AUTOINCREMENT ,age INTEGER)";
db.execSQL(s);
}
catch (Exception e)
{
System.out.println("Exception 1:"+e);
}
finally
{
db.endTransaction();
}
try
{
db.beginTransaction();
db.execSQL("INSERT INTO test VALUES(NULL,22)");
db.setTransactionSuccessful();
System.out.println("Insert ok.");
}
catch (Exception e)
{
System.out.println("Exception 2:"+e);
}
finally
{
db.endTransaction();
}
Can someone tell what is happening?
It's normal behaviour. Your table wasn't created because you didn't commit TRANSACTION as well as your insert wasn't performed. Reason why you are getting result
System.out.println("Insert ok.");
is that execSQL() method throws SQLException only in the case if your query string is invalid / broken. And also you can't use execSQL() for inserting. You can use it only for altering tables.
Execute a single SQL statement that is NOT a
SELECT/INSERT/UPDATE/DELETE.
Solution:
Since execSQL() is void type you need to use API method insert() to test result.
long rowId = db.insert("test", <nullColumnHack>, values);
if (rowId < 0) {
// error
}

SQLiteDatabase.insertOrThrow doesn't throw but not data is inserted

I'm trying to get familiar with Android and its database API.
I've created a class that inherits from SQLiteOpenHelper and this
is how I create the table in the database
#Override
public void onCreate(SQLiteDatabase db) {
try {
db.execSQL("CREATE TABLE " + FUELS_TABLE_NAME + " ("
+ "_ID INTEGER PRIMARY KEY AUTOINCREMENT, "
+ "DATE_OF_FUELS DATE DEFAULT CURRENT_TIME,"
+ "SELLER_POSITION TEXT DEFAULT 'unknown',"
+ "AMOUNT REAL"
+ ");"
);
} catch (SQLException e) {
Log.e(DATABASE_NAME, e.toString());
}
}
The function used to add data to the DB is the following implemeneted within
the same class is
public void addNewFuel(float amount) {
// Create the content to insert into the database
ContentValues newEntry = new ContentValues();
newEntry.put("amount", amount);
// Get database handler
try {
db = getWritableDatabase();
} catch (SQLException e) {
Log.e(DATABASE_NAME, e.toString());
return;
}
// Begin transaction and insert data
long returnedValue;
db.beginTransaction();
try {
returnedValue = db.insertOrThrow(FUELS_TABLE_NAME, null, newEntry);
Log.v(DATABASE_NAME, "return value " + returnedValue);
} catch (SQLException e) {
Log.e(DATABASE_NAME, e.toString());
} finally {
db.endTransaction();
}
db.close();
}
but apparently no data is added. The returnValue is always 1. The method doesn't throw,
and when I pull out the DB with adb and look at it's content is totally empty.
I just can't understand what I'm missing.
Any suggestion would be appreciated.
Thanks,
S
McStretch's answer is incorrect. getWritableDatabase() does not create a transaction for your code, the quoted line from the docs is referring to transactions being used for the onCreate and onUpgrade methods meaning that you don't need to add transaction code in those methods. You still need add transaction code for any other method that requires transactions.
emitrax's code is not working correctly as db.setTransactionSuccessful() is not being called which means the transaction will be rollbacked by db.endTransaction().
See benritz's answer for the correct solution. This answer is incorrect, but I'm unfortunately not able to delete it since it's an accepted post.
/******* NOT CORRECT!!
Since you're inheriting from SQLiteOpenHelper, your call to getWritableDatabase() already starts a DB transaction. From the SQLiteOpenHelper API:
Transactions are used to make sure the
database is always in a sensible
state.
Thus you don't need to call db.beginTransaction() and db.endTransaction(). Those extraneous transaction calls are messing up your inserts. I plugged the same scenario into my project and found that the same index (6 in my case), was returned when using those transaction methods. When I remove the calls I get my desired results (multiple records inserted).
NOT CORRECT!! *******/

SQLite table query

I query the table by using this function below
public Cursor getTableInfo() throws SQLException
{
return db.query(TableName, null,
null,
null,
null,
null,
null);
}
I got the error "View Root.handleMessage(Message)line:1704". I could insert the data but can't query the data. I called this function below
Cursor c = db.getTableInfo();
int cRow = c.getCount();
if (cRow == 0)
{
Toast.makeText(NewContact.this,
"No Record",
Toast.LENGTH_LONG).show();
}
In SQLite, is there any case-sensitive in the name of database, table, column?
Please help me.
Your db request looks ok and it should return all records from your table.
So maybe there are just no records in the table?
Also it's unclear whether you have problem with db related stuff or with smth else, because the code provided looks ok.
I would rather evaluate the outcome of c.moveToFirst() instead of c.getCount(). The latter means the cursor iterates over the whole dataset which is a more costly operation.

Categories

Resources