try {
db.insertOrThrow("savedreports", null, cv);
} catch (SQLException e) {
Log.e(TAG, e.getMessage(), e);
}
If the code above is executed trying to insert duplicate record (same primary key and fields values as well) what error message will the exception give?
"PRIMARY KEY must be unique"
or
"UNIQUE constraint failed"
or
???
My program will grab some records from a server and then informs the server to delete those records. However sometimes the http request to delete the records fails due to bad connection, hence I would get the same records when I rerequest for the latest records.
I currently insert these records using insertOrThrow, hence when the duplicate records occur, I would like to know exactly the exception thrown it's exactly due to duplicate records (and not due to null column constraint, database connection close or etc).
These constraints are designed to detect programming errors, not runtime errors. Therefore, there is no guaranteed error message.
If you want to check that the key is not a duplicate, you have to do the check yourself.
But if this is the only constraint that can fail, you can INSERT OR IGNORE instead (insertWithOnConflict() in Android).
Related
I migrated from ormlite to Android Room
I use custom query which can fail, but I don't find how to handle the exception
try {
appDatabase.query(new SimpleSQLiteQuery(sql));
} catch (SQLException e)
{
// custom code
}
how can i achieve this with android rooms ?
That type of query fail with some version of sqlite
INSERT INTO country(id,continent,name)
SELECT 1,'Asia','Afghanistan' UNION
SELECT 2,'Africa','Egypt'
of course there are a lot of line, and it was made for performance reasons. If it fail, I run a fail sql batch
that type of query is supported from a sqlite version BUT there are device which don't support it, even it has the required version. (so I'd like to know when there is an error)
I have a method that runs a INSERT SQL statment that are got from external soruces and not from the android device. The incoming statments can cause duplicate records and I want the android device to ignore the sql statments if they cause duplicates. The method is:
ourDatabase.execSQL(sql)
The table its inserting the data into has the following column that prevents duplicates
KEY_CONCATA + " TEXT PRIMARY KEY , " +
Should this be unique and not primary key?
The system at the moment recognizes its causing a duplicate and ends the program, I want it to catch the error and stop it being inserted into the database if its a duplicate.
Thanks!
Declare KEY_CONCATA TEXT NOT NULL UNIQUE and when insert use insertWithOnConflict with SQLiteDatabase.CONFLICT_IGNORE flag
in my android application my plan is to run a bunch of insert statements using SQLiteDatabas object.
What I want is when the insert statement violates the unique constraint such that I could know in what insert statement the error happens and that insert statement doesn't affect the DB.
Does any one know how to do that? I saw insertWithOnConflict and insertOrThrow method. Can I know form the first method when a unique constraint violation occured?
What I want is when the insert statement violates the unique constraint such that I could know in what insert statement the error happens and that insert statement doesn't affect the DB.
If the INSERT statement violates the unique constraint, it will not affect the database, by definition. It will throw a SQLiteException. If you need to know specifically which INSERT violates the constraint, execute them one at a time, wrapped in your own transaction (beginTransaction(), setTransactionSuccessful(), endTransaction()).
I have looked through several sites for any useful documentation and have come up empty. The flow charts from the official site might as well be greek and examples I have attempted from other relevant posts on this site have gotten me errors. I am writing a simple app to place user input in a database, however I need a combination of 2 columns to be unique. From what I have seen this can be accomplished with UNIQUE or PRIMARY KEY. I also need some way of capturing the error to Toast the user that their input is faulty. I know that I can do this in the Java side easily enough yet I would prefer not to loop through the table on every proposed insert.
This is what I have so far:
db.execSQL("CREATE TABLE inventory (category TEXT, itemNum TEXT, quantity INTEGER, price REAL, image INTEGER, UNIQUE(category, itemNum) ON CONFLICT FAIL;");
The table constructed properly until I added UNIQUE...
Which threw:
ERROR/SQLiteOpenHelper(1037): android.database.sqlite.SQLiteException: near ";": syntax error: CREATE TABLE inventory (category TEXT, itemNum TEXT, quantity INTEGER, price REAL, image INTEGER, CONSTRAINT unq UNIQUE(category, itemNum) ON CONFLICT FAIL;
EDIT:
... fill ContentValues values with user input.
try{
db.getWritableDatabase().insert(DatabaseHelper.TABLE_NAME, DatabaseHelper.CATEGORY, values);
fillItemNumbers(); // Updates screen
}
catch(SQLiteConstraintException e)
{
Toast
.makeText(this, "User error",Toast.LENGTH_LONG)
.show();
}
You have mismatched parenthesis. There should be another ) after FAIL.
Once you've sorted that, you can catch the exception that happens when the constraint is breached.
try {
// insert new data
} catch (SQLiteConstraintException e) {
Toast.makeText(context,
"The combination of A and B must be unique",
Toast.LENGTH_LONG).show();
}
I'm developing an Android 2.2+ app with SQLite db support. I'm trying to define referential integrity constraints while creating the tables. I've also enabled the foreign key support by executing db.execSQL( "PRAGMA foreign_keys=ON;" ); in onCreate and onOpen methods of SQLiteOpenHelper. Afteer setting up my tables and proper foreign key references, it still allows me to insert rows in tables where reference records are missing. For e.g. I've following structure
CREATE TABLE Questions(_id integer primary key,question text not null);
CREATE TABLE Ques_Ans(_id integer primary key autoincrement,qid integer not null,
aid integer not null,is_correct integer default 0,
FOREIGN KEY (qid) REFERENCES Questions(_id));
and following my data in the table
INSERT INTO Questions VALUES(1, 'Some text');
INSERT INTO Ques_Ans(qid, aid, is_correct) VALUES(20, 1, 0);
If foreign key is properly set on Ques_Ans table, 2nd insert should have failed as there is no record in Questions table with id 20, but somehow my app does not thrown any error and inserts the 2nd insert statement. Can anybody tell me whats wrong over here or am I missing any configuration over here?
Update [03-Mar-2012]: After discussion thread with #Catcall
Using sqlite3 tool, switching on PRAGMA foreign_keys=ON; foreign key works as expected
Same thing if used via app on Emulator or on Phone does not work
Insert statements executed using insert() or execSQL(). None of them throw foreign key constraint failed error
PRAGMA integrity_check returns ok. So database is not corrupt.
Your foreign key is on the column "qid", not on the column "_id".
This INSERT statement
INSERT INTO Ques_Ans VALUES(20, 1, 0);
should have thrown the error
Error: table Ques_Ans has 4 columns but 3 values were supplied
This INSERT should succeed.
INSERT INTO Ques_Ans VALUES(20, 1, 0, 0);
This one should fail.
INSERT INTO Ques_Ans VALUES(21, 2, 0, 0);
Error: foreign key constraint failed
Later . . .
Since it works in sqlite, but not in your emulator, the problem is probably in either the emulator or your code.
This is the idiom for database transactions.
db.beginTransaction();
try {
...
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
Android docs suggest using insert() instead of execSQL(). Make sure you're trapping, catching, or checking for errors in every function that can return an error. So, for example, if you switch to insert(), check its return value for -1.
If that doesn't help, you might try tagging this question with "Java" (for example), or asking a new question that focuses on your code and on catching errors.
IN SQLite Foreign key constraints are disabled by default (for backwards compatibility). You have to enable it explicitly using
PRAGMA foreign_keys = 1
after you establishing your connection with the database. Here's the link to the official docs that explains it in more depth. http://sqlite.org/foreignkeys.html Please navigate to enabling foreign key support in the above link.