I am fetching and storing phone numbers and contact names in a SQLite DB from an Android phone. Now my problem is that whenever I refresh/reload the app the SQL entries (phone and contacts) are inserted again and again giving rise to duplicate entries. How to stop this, I am using Phonegap, by the way!
I am using this simple code to populate the DB
tx.executeSql('CREATE TABLE IF NOT EXISTS details (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, phone TEXT)');
But it is causing double entries.
Stopping this can be as easy as defining a two field primary key, like this :
CREATE TABLE contacts(
name CHAR(10) NOT NULL,
address INTEGER,
phone INTEGER NOT NULL,
song VARCHAR(255),
PRIMARY KEY (name, phone)
)
This key will ensure no entry in the database has the same name and phone.
Hope this helps !
It will solve the duplicate entry problem:
sampleDB.execSQL("INSERT OR REPLACE INTO measure_table (measure) " + "VALUES ( '" + "Length" + "')");
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'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 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 currently have a table called User which has a id column which is created as
'INTEGER PRIMARY KEY'
Lets say I have created two users so the table has id 1 and 2
If I delete the second user and create a third the id is 2, I need this to be 3
So it seems Android is selecting the next available id, how can I change this to its more like a sequence number?
Regards
Make it INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL. Here's what the docs say:
If a column has the type INTEGER PRIMARY KEY AUTOINCREMENT then... the ROWID chosen
for the new row is at least one larger than the largest ROWID that has
ever before existed in that same table.
The behavior implemented by the AUTOINCREMENT keyword is subtly
different from the default behavior. With AUTOINCREMENT, rows with
automatically selected ROWIDs are guaranteed to have ROWIDs that have
never been used before by the same table in the same database. And the
automatically generated ROWIDs are guaranteed to be monotonically
increasing.
SQLite AUTOINCREMENT is a keyword used for auto incrementing a value of a field in the table. We can auto increment a field value by using AUTOINCREMENT keyword when creating a table with specific column name to auto incrementing it.
The keyword AUTOINCREMENT can be used with INTEGER field only.
Syntax:
The basic usage of AUTOINCREMENT keyword is as follows:
CREATE TABLE table_name(
column1 INTEGER AUTOINCREMENT,
column2 datatype,
column3 datatype,
.....
columnN datatype,
);
For Example See Below:
Consider COMPANY table to be created as follows:
sqlite> CREATE TABLE TB_COMPANY_INFO(
ID INTEGER PRIMARY KEY AUTOINCREMENT,
NAME TEXT NOT NULL,
AGE INT NOT NULL,
ADDRESS CHAR(50),
SALARY REAL
);
Now, insert following records into table TB_COMPANY_INFO:
INSERT INTO TB_COMPANY_INFO (NAME,AGE,ADDRESS,SALARY)
VALUES ( 'MANOJ KUMAR', 40, 'Meerut,UP,INDIA', 200000.00 );
Now Select the record
SELECT *FROM TB_COMPANY_INFO
ID NAME AGE ADDRESS SALARY
1 Manoj Kumar 40 Meerut,UP,INDIA 200000.00
If speaking for ANDROID, yes, above answers are correct, except naming of the id column.
database.execSQL("CREATE TABLE IF NOT EXISTS "
+ TableName
+ " ( rowid INTEGER PRIMARY KEY AUTOINCREMENT, Raqam VARCHAR, ChandBor INT(3));");
It looks like in Android it should be named as 'rowid'.
And with Cursor you need to instantiate it like:
Cursor cursorLcl = database.rawQuery("SELECT *," + TableName + ".rowid AS rowid" + " FROM " +
TableName, null);
Otherwise it didnt work for me. I don't know why it so.
Just remember for android when writing tot the database (ie. executing),
do
INSERT INTO TABLE_NAME (param1name, param2name) VALUES (param1,param2)
and there is no need to add a place holder for the auto increment. It will add it by itself when adding a record. If you do not declare the params that you will put in, you will get the error x amount of variables expected and you only gave x-1, and this is because you are not supposed to give any place holding value for the auto increment column