I have a common problem, and have looked at several solutions but haven't seen one that fits this case.
I have a temporary table that is defined as follows:
public static final String GROUP_TABLE_CREATE =
"CREATE TEMP TABLE "+GROUP_TABLE_NAME+" ("
+GROUP_ID_COLUMN_NAME+" INTEGER PRIMARY KEY AUTOINCREMENT, "
+GROUP_GROUP_ID_COLUMN_NAME+" INTEGER NOT NULL UNIQUE, "
+GROUP_COLUMN_NAME+" VARCHAR(64) NOT NULL)";
The table is created without any problems. I then download some data to insert into it and use the following query to insert it:
ContentValues contentValues = new ContentValues();
contentValues.put(WhereWolfOpenHelper.GROUP_GROUP_ID_COLUMN_NAME, groupID);
contentValues.put(WhereWolfOpenHelper.GROUP_COLUMN_NAME, groupName);
db.insert(WhereWolfOpenHelper.GROUP_TABLE_NAME, null, contentValues);
And then I get the following error:
08-05 08:52:37.791: ERROR/Database(847): Error inserting group_name=Friends group_id=2
08-05 08:52:37.791: ERROR/Database(847): android.database.sqlite.SQLiteConstraintException: error code 19: constraint failed
The error appears twice, and the only data in the database is the group named Friends (there should be two more entries).
I have another table with very similar code that works without any problems, so I'm guessing it's just some silly mistake that I haven't spotted. Anyone got any ideas?
If "constraint failed" than something in table scheme should tell us what is wrong.
I see what it show data what it want to insert, this means what NOT NULL constraint is OK.
In this case I've only one assumption what you already inserted some GROUP_GROUP_ID_COLUMN_NAME with value 2 and UNIQUE constraint is failed because of that.
Are you using a temporary table on purpose? A temporary table dies once the DB connection is closed. If this is the case, the table will get created and the insert will not correspond to any table. So the constraint 19 can correspond to 'Table not found'
You shouldn't pass null values in insert method. Pass empty strings.
Related
I'm new to coding android apps with Sqlite
I have three questions
I created this Sqlite table with columns with attributes like
TEXT
NOT NULL
UNIQUE
DEFAULT regular
Q1) I'm skeptical to know whether is there any order on how to delare attributes for a row
Q2) If I declare any row to have a default value like will the text be still inserted even though the user inserts something in that row, if yes, then how to insert a default value if the user dosen't inset any value in a specific Row
Q3)Is my code below correct ? What I desire is the row KEY_TAGNAME to be unique, not null and to have a value if the row doesn't get any data while a insert statement occurs for that table.
private static final String CREATE_TAGTABLE_SQL=
"CREATE TABLE " + DATABASE_TABLE_TAG
+ " ("
+ KEY_TAGROWID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ KEY_TAGNAME + " TEXT NOT NULL UNIQUE DEFAULT regular"
+ ");";
A1: I couldn't find anything in the documentation that clearly says anything about the order of the attributes but I tried to create a couple of tables in a test database I created to check this and it seems that if you do not follow the proper order you will get a syntax error.
(tried with create table test (key1 integer primary key autoincrement) which works correctly but create table test1 (key1 primary key integer autoincrement) gives a near "integer": syntax error:
A2: You can have a default value inserted that will be put if the user does not input anything there. The keyword is default and you will find more info here on how to use it (TL;DR upon table's creation you will create the row as usual and in the end put a DEFAULT and next to it the value. Please check the link on this)
A3 Your query is correct and will do the things you mention.
I have a table with 4 fields: _id, to, from, hidden
Upon trying to insert the following values:
_id=167 from=1311005879000 to=1311005879000 hidden=0
into my table, I got an SQLiteConstraintException stating that
'column _id is not unique (code 19)'
To find the cause for this problem I tried querying the size of the table and found it is 0, so I have no idea where this is coming from.
Maybe I didn't understand the error correctly?
Edit: some code!
try {
mDatabase.insertOrThrow("groups", null,
mContentValues);
} catch (SQLException e) {
e.printStackTrace();
}
Creation SQL:
CREATE TABLE IF NOT EXISTS groups(_id LONG PRIMARY KEY,hidden INTEGER,from LONG,to LONG
'column _id is not unique (code 19)'
So you are violating UNIQUE Constraint. This is reason of SQLiteConstraintException. Your _id column is most likely primary key and primary keys have implicitly assigned UNIQUE constraint that say no two rows can have same primary key.
You are trying to insert duplicit _id that already is in db or PK is assigned to NULL.
I tried querying the size of the table and found it is 0, so I have no
idea where this is coming from.
I think your query was broken because your Exception says everything and it cannot be thrown if somewhere is not a problem.
Update:
If you are not assigned NULL to PK and also your table has 0 records probably problem is here:
mDatabase.insertOrThrow("groups", null, mContentValues);
You are assigned NULL to ColumnHack as second param of insert() method that you shouldn't. In SQLite, each row must have at least one column specified. It needs one column that can be safe assigned to NULL.
I have created one Member_Master table whose primary key is member_id in sqlite manager for android and creating foreign key in child table e.g Event_Master for member_id from Member_Master. I was getting no such table found:Member_Master error
But now I am getting the following error :
SQLiteManager: CREATE TABLE "main"."Events_Master" ("event_id" NUMERIC PRIMARY KEY NOT
NULL ,"event_name" TEXT NOT NULL ,"event_details" TEXT NOT NULL ,"event_start_date"
DATETIME NOT NULL ,"event_end_date" DATETIME NOT NULL ,"event_time" DATETIME NOT NULL
,"event_venue" TEXT NOT NULL ,"min_level" NUMERIC,"status_id" NUMERIC,"member_id"
NUMERIC, foriegn key(member_id) references Member_Master(member_id)ON DELETE CASCADE ON
UPDATE CASCADE) [ near "member_id": syntax error ]
Exception Name: NS_ERROR_FAILURE
Exception Message: Component returned failure code: 0x80004005 (NS_ERROR_FAILURE)
[mozIStorageConnection.createStatement]
Please give me the solution. Since Member_Master table is already created and field name is member_id only.
If you are getting no such table exception, the reason for this is that the table is not created.There can be few reasons like
1 ) The command you have used to create the table is is wrong (and could be a typing error also).
2 ) You are adding a table in an already existing database
When Database is created with specific number of tables you can not add more tables to it .
If you want to add more tables, you need to uninstall the application from your emulator and install the application again only then it shall create the new tables by re creating the database.
Or upgrade the database version , it shall drop all the tables once and then recreate the database.
Try uninstalling the app and reinstall it again. it works most of the times.
If you are getting no such table exception, then It is sure that the tables are not getting created.Have You written create Table query in your DatabaseAdapter class or simply adding a table from SqliteManager.
If you are creating tables dynamically, please write CREATE TABLE query and execute Query.
I am trying to insert data to a new empty table. But I keep getting error (error code 19: constraint failed). I think the problem may caused by 'INTEGER PRIMARY KEY AUTOINCREMENT'. Here is my code:
database.execSQL("CREATE TABLE IF NOT EXISTS contacts (cid INTEGER PRIMARY KEY AUTOINCREMENT, name varchar NOT NULL, user varchar NOT NULL, UNIQUE(user) ON CONFLICT REPLACE)");
...
String sql = "INSERT OR IGNORE INTO contacts ( name , user) VALUES (?, ?)";
database.beginTransaction();
SQLiteStatement stmt = database.compileStatement(sql);
stmt.bindString(1, name);
stmt.bindString(2, entry.getUser());
int i = (int)stmt.executeInsert();
stmt.execute();
stmt.clearBindings();
stmt.close();
// error: 06-11 20:50:42.295: E/DB(12978): android.database.sqlite.SQLiteConstraintException: error code 19: constraint failed
Anyone knows what wrong with the sql statement? How can I solve this problem? Thanks
I have read few articles on stackoverflow. But cannot find anyone post related to 'insert or replace' + 'INTEGER PRIMARY KEY AUTOINCREMENT'.
I think your code is doing exactly what it is supposed to be doing. Reading over your code it looks like you want it to ignore inserts where there is already something inserted. The error you are receiving is telling you that the insert has failed.
If you use INSERT IGNORE, then the row won't actually be inserted if it results in a duplicate key. But the statement won't generate an
error. It generates a warning instead. These cases include:
Inserting a duplicate key in columns with PRIMARY KEY or UNIQUE
constraints. Inserting a NULL into a column with a NOT NULL
constraint. Inserting a row to a partitioned table, but the values you
insert don't map to a partition. - "INSERT IGNORE" vs "INSERT ... ON DUPLICATE KEY UPDATE"
I would recommend catching the SQLiteConstraintException or check before inserting to see if the data is already there. If you need some ideas on how to check if data has been inserted let me know, I have had to do this before. Hope this helps.
There is a good begining to end example of SQLite on Android written by Lars Vogella here
Inside there and down a little ways here is the string that he uses for creating a table:
// Database creation sql statement
private static final String DATABASE_CREATE = "create table "
+ TABLE_COMMENTS + "(" + COLUMN_ID
+ " integer primary key autoincrement, " + COLUMN_COMMENT
+ " text not null);";
I have not tried either his or yours just now but a few things I noticed that differ between his and yours are:
He has no space between the table name and the opening parenthesis
He has a semicolon inside of the SQL string. after the closing parenthesis.
I am not certain if those will fix it for you, but it would probably be a good start.
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.