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.
Related
my_table(ID INTEGER PRIMARY KEY AUTOINCREMENT, Name NVARCHAR(100))
I deleted all of the data in SQLiteDatabase by the command "DELETE FROM my_table". It's was a success, but I have one trouble: When I insert new data into my_table, ID auto-increment with the old ID, It means have field memory is existing in my program. Can you help me solve it? Thank everybody
enter image description here
In SQLite, there is an internal table called sqlite_sequence which stored information about autoincrement columns. To reset autoincrement value, you can execute command:
"DELETE FROM SQLITE_SEQUENCE WHERE NAME = '" + my_table + "'"
Simple problem which got me stuck for hours now...
When I add a value into my database via db.insert(TABLE_NAME, null, myValues) the new id of my item is returned.
Exactly after this call I'd like to update my entry. Therefore I call db.update(TABLE_NAME, values, MY_ID_NAME + " = " + returnedId, null). I'd expect to get 1 returned as one entry is affected by this update.
However, I get 0. My id is simply not saved into the database. If I try more complex queries I always get every value I need but the id, which is always 0.
I've no idea how to find my fault - I get a cursor, try to get the id by long id = cursor.getLong(0) and it will return 0.
My CreateStatement starts with:
"CREATE TABLE " + TABLE_NAME + "("+ MY_ID_NAME + " LONG PRIMARY KEY, "....
Also I need to mention that I work on an In-Memory Database for testing purposes.
What is missing? What am I doing wrong?
Also: I decided to open the database only at the beginning via Singleton-Pattern - this wasn't an issue until now
Edit2: What I also forgot to mention is that I'm currently working in an InstrumentationTestCase-environent for some unit-tests
I'm almost positive that the primary ID number in Android's SQLite must be called _id during table creation and referred to when querying the table as _ID.
so in this case:
"CREATE TABLE " + TABLE_NAME + "(_id LONG PRIMARY KEY, "....
Edit:
Try this:
"CREATE TABLE " + TABLE_NAME + "("+ MY_ID_NAME + " LONG PRIMARY KEY AUTOINCREMENT, "...
Although I am curious why you choose to use LONG instead of INTEGER
After hours of testing and debugging, Zolnoor's answer was nearly correct:
SQLite does not allow a LONG PRIMARY KEY statement but an INTEGER PRIMARY KEY as described in the SQLite-Documentation:
The data for rowid tables is stored as a B-Tree structure containing one entry for each table row, using the rowid value as the key. This means that retrieving or sorting records by rowid is fast. Searching for a record with a specific rowid, or for all records with rowids within a specified range is around twice as fast as a similar search made by specifying any other PRIMARY KEY or indexed value.
With one exception noted below, if a rowid table has a primary key that consists of a single column and the declared type of that column is "INTEGER" in any mixture of upper and lower case, then the column becomes an alias for the rowid. Such a column is usually referred to as an "integer primary key". A PRIMARY KEY column only becomes an integer primary key if the declared type name is exactly "INTEGER". Other integer type names like "INT" or "BIGINT" or "SHORT INTEGER" or "UNSIGNED INTEGER" causes the primary key column to behave as an ordinary table column with integer affinity and a unique index, not as an alias for the rowid.
I have couple of tables which will have new data every time the user logs into the application. I have a column KEY_ROWID which is autoIncrement. I want it to always start with 1.
I tried truncating the table before new data is inserted. I get an error:
"android.database.sqlite.SQLiteException: near "TRUNCATE": syntax
error (code 1): , while compiling: TRUNCATE TABLE StaffListTable"
Sugestions much appreciated.
private static final String CREATE_TABLE_STAFFLIST = "CREATE TABLE " + TABLE_STAFFLIST + " ("
+ KEY_ROWID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ KEY_STAFFID + " TEXT NOT NULL, "
+ KEY_STAFFNAME + " TEXT NOT NULL);";
Its very simple, since you are truncating the table values I understand you don't have to secure them or take a back up. In such a case just dropping the table will do the trick.
In onUpdate() method, write
db.execSQL("DROP TABLE IF EXISTS "+DATABASE_TABLE); //and call onCreate again
onCreate(db);
Let me know if you need anything else. Happy coding. :)
There's no TRUNCATE in sqlite. You can use DROP to delete tables if you really need to.
There are two ways to effect a truncate (which SQLite doesn't have). You can either DROP and then CREATE as per other answers here.
Alternatively you can do a DELETE to empty the table and then remove the entry for the table from sqlite_sequence:
DELETE FROM sqlite_sequence
WHERE name = 'table_name'
sqlite_sequence holds the last used autoincrement value for tables with such columns. Removing the row for a given table will make the autoincrement key start at 1 again.
I'm trying to create a table and I've tried so many times to figure this out... for some reason it won't accept this.. it's saying something about the auto_increment
create table if not exists Assignments(
id auto_increment primary key,
class_name VARCHAR(30),
assignment_name VARCHAR(30) not null,
due_date VARCHAR(30) not null,
notes VARCHAR(30));
whats the problem?
EDIT: i am trying to use SQLite eventually but this command was written on my mySQL thru WAMP
First of all, Android uses SQLite, so your mysql tag is slightly incorrect unless I'm missing something you're doing.
Secondly, you would say
CREATE TABLE ASSIGNMENTS(id INTEGER PRIMARY KEY, class_name TEXT, assignment_name TEXT NOT NULL, due_date TEXT NOT NULL, notes TEXT);
"autoincrement" is handled automatically if you set your primary key as an INTEGER type, even though under the covers SQLite uses strings for everything
reference: SQLite datatypes
further reference: INTEGER PRIMARY KEY
Even more reference: "If an INSERT statement attempts to insert a NULL value into a rowid or integer primary key column, the system chooses an integer value to use as the rowid automatically. A detailed description of how this is done is provided separately."
It is autoincrement, not auto_increment
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.