How create table behaves in transactions? - android

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
}

Related

Does it exist any SQLite lock can prevent to query a record?

I have an upsert method in my Android app. It query a record by id, and if it does not exist INSERT anyway UPDATE is performed.
DB can be modified quite frequently. I do not know much about SQLite locking mechanism.
Is it possible that some lock is retained on a record and so query will not return it?
If exception occurs on an INSERT operation like:
android.database.sqlite.SQLiteConstraintException: column _id is not unique (code 19)
Can I perform an UPDATE in catch clause?
I tryed REPLACE INTO, but it has no effect. Not crashes, but has no effect:
String queryString = "REPLACE INTO " + recordType + " (" + keys + ") VALUES (" + values + ")";
statement.executeUpdateDelete(); // <-- tried all 3 option: execute, executeInsert, executeUpdateDelete
You can either use insertWithConflict() and specify SqliteDatabase.CONFLICT_REPLACE, or you can wrap your logic in a transaction:
db.beginTransaction();
try {
// query for record
// if found, update; otherwise, insert
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}

SqlLiteDatabase catching exception

I have my table in database
CREATE TABLE Opponent (
Opponent_ID integer PRIMARY KEY AUTOINCREMENT,
Opponent_Add_Date text,
Opponent_Name text UNIQUE
);
Then I'm trying to insert query to database
String query = "INSERT INTO Opponent (Add_Date, Opponent_Name) VALUES ('date' , 'name');"
The problem occurs, when I want to add existing opponent name, my app crushes. If I'm trying to catch my exception with SQLiteConstraintException, however then it allows adding two Opponents with the same name. For catching it I'm using:
try {
SQLiteStatement statement = mDataBase.compileStatement(query);
statement.execute();
} catch (SQLiteConstraintException e) {
Log.e("insert", "SQLException: " + e.getLocalizedMessage());
}
Could anyone tell me how to catch the moment, when two the same names are added?
If you just want to do nothing if the name already exists, then you can use INSERT OR IGNORE instead.
However, if you also need to retrieve the ID of the already-existing row, then you should just execute a SELECT first, and do the INSERT only if the row is not found.

Avoid sqliteAssetHelper to log error

Hi guys i'have problem with this little block of code
// Insert a new contact in database
public void insertInSignature(String TITLE_SI) {
try {
// Open Android Database
db = databaseHelper.getWritableDatabase();
ContentValues initialValues = new ContentValues();
initialValues.put("TITLE_SI", TITLE_SI);
db.insert("DELIVERY_SLIP", null, initialValues);
} catch (SQLException sqle) {
Log.e(TAG, "insertUser Error");
Log.e(TAG, "Exception : " + sqle);
} finally {
// Close Android Database
databaseHelper.close();
}
}
I have unique constraint on my table "DELIVERY_SLIP
So , when i'm trying to insert some row which already exist , it return some error like "Oh shit , you're inserting the same , i'm sorry men , i can't do it"
http://cdn.imghack.se/images/3b51afd07d1f1a8bd021c9e9dfc57e98.png
Here my log
It's this line
databaseHelper.close();
When database helper close , this return the log.
I just want to avoid to log it, I already tested with a tryCatch on sqliteConstraintException
But, nothing worked.
Thanks by advance
Instead of insert(), use insertWithOnConflict() with some conflict resolution algorithm appropriate for your use, such as SQLiteDatabase.CONFLICT_IGNORE.

Java.lang.outofmemory error while performing sqlite database operation

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.

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!! *******/

Categories

Resources