Android SQLite Database After delete table, will the id starts from 1? - android

I have a doubt that if i delete the table using following statements,
SQLiteDatabase db = this.getWritableDatabase();
db.delete(date_difference, null, null);
then if i'm inserting a row as a fresh and first record into the table, will the id primary key auto increment of the records starts from 1 ?

If no ROWID is specified on the insert, or if the specified ROWID has
a value of NULL, then an appropriate ROWID is created automatically.
The usual algorithm is to give the newly created row a ROWID that is
one larger than the largest ROWID in the table prior to the insert.
If the table is initially empty, then a ROWID of 1 is used. If the largest ROWID is equal to the largest possible integer
(9223372036854775807) then the database engine starts picking positive
candidate ROWIDs at random until it finds one that is not previously
used.
So yes, after you delete the table, IDs will start from 1
http://www.sqlite.org/autoinc.html

The documentation provided states that that delete method is a:
Convenience method for deleting rows in the database.
The syntax is:
int delete(String table, String whereClause, String[] whereArgs)
Therefore it won't start from 1 again. It'll continue on from the last increment. If you deleted the whole table, then re-created it, the increment would begin at 1.

SQLite keeps track of the largest ROWID that a table has ever held using an internal table named "sqlite_sequence". The sqlite_sequence table is created and initialized automatically whenever a normal table that contains an AUTOINCREMENT column is created**.
The content of the sqlite_sequence table can be modified using ordinary UPDATE, INSERT, and DELETE statements**. But making modifications to this table will likely perturb the AUTOINCREMENT key generation algorithm. Make sure you know what you are doing before you undertake such changes.
So when you delete your table and you re-create it, you should make the SQLITE_SEQUENCE restart from 0.
You should do something like this :
Delete from date_difference;
Delete from sqlite_sequence where name='date_difference';
Care because the field 'table name' in where clause is case sensitive.
Read this for more informations.

Define the primary key field as
INTEGER PRIMARY KEY AUTOINCREMENT DEFAULT 1
Then remove the code if you are doing insertion of any value for the primary key field like following
values.put(KEY_PRIMARY, object.getIntegerValue());

Related

how can we get the id of a row that we insert through code

I need to retrieve the id of the row inserted just now. ie, i have a table for words and a table for meaning. i need the wordId of the word i insert in the table for words and that wordId is used for inserting the meaning in meaning table. Can anyone help me out??
I thought i could use trigger and tried the trigger:
"CREATE TRIGGER IF NOT EXISTS word_insert_trigger AFTER INSERT ON tb_words BEGIN select NEW.word_id from tb_words; END;"
like this. i tried this in sqlite dbbrowser. but it didn't work out.
i need the row id when i insert a row like this :"insert into tb_words(word_name) values('test');"
How can i do that without using "SELECT last_insert_rowid()"? like in the following link:
How to retrieve the last autoincremented ID from a SQLite table?
No need for a trigger. Use the SQliteDatabase insert method. It returns the id (as a long) (more correctly it returns the rowid and assuming that the word_id column has been defined as an alias of the rowid column, then the returned value will be the value assigned to the word_id column).
An alias of the rowid column is defined if word_id INTEGER PRIMARY KEY is coded (the AUTOINCREMENT key may be used BUT in generally should not be used).
You may wish to read SQLite AUTOINCREMENT and/or Rowid Tables
Instead of something like :-
db.execsql("insert into tb_words(word_name) values('test');");
You would use something like :-
ContentValues cv = new ContentValues();
cv.put("word_name","test");
long word_id = db.insert("tb_words",null,cv);

SQLite - integer PRIMARY INDEX constraint failing?

In my Android app, I create a FULLTEXT table like this:
CREATE VIRTUAL TABLE products USING fts3 (
_id integer PRIMARY KEY,
product_name text NOT NULL,
...
)
And I add this index:
CREATE INDEX product_name_index ON products (product_name)
The app populates the table with various products, each with a unique _id value.
However, when I then try to insert an already-existing product ID (using an _id value that is already in the table, but with a different product_name value) like this:
long rowId = db.insertOrThrow("products", null, contentValues);
a new row is added to the table (with a brand new rowId value returned)!
I expected the insertOrThrow command to fail, so where am I going wrong? Is it something to do with the fact that it's a FULLTEXT table or could the index I specified on the product_name column be messing things up somehow?
I read this section about INTEGER PRIMARY KEY, but unfortunately I'm none the wiser.
Update
When I try to perform the same operation on a standard (non-FULLTEXT) table, then the insertOrThrow command results in the expected SQLiteConstraintException.
I think the issue might be that an FTS table has the concept of a docid and a rowid column and specifying null for the docid results in that being given a value.
as per :-
There is one other subtle difference between "docid" and the normal
SQLite aliases for the rowid column.
Normally, if an INSERT or UPDATE
statement assigns discrete values to two or more aliases of the rowid
column, SQLite writes the rightmost of such values specified in the
INSERT or UPDATE statement to the database.
However, assigning a
non-NULL value to both the "docid" and one or more of the SQLite rowid
aliases when inserting or updating an FTS table is considered an
error. See below for an example.
1.3. Populating FTS Tables

How can i delete every value row in my SQLite Table?

I want to delete all my values in my sqlite Table.
When I click my button it deletes everything besides the id it keeps counting
so for example:
ID, FIRSTNAME, LASTNAME
1, Jack Sparrow
2, Johhny Dep
if I press delete and add new values, it shows this
ID, FIRSTNAME, LASTNAME
2, Obama Barack
3, Mike Tyson
this is my method
private void DeleteEverything()
{
SQLiteDatabase db = mDbHelper.getWritableDatabase();
db.execSQL("delete from "+NamesContract.NameEntry.TABLE_NAME);
}
You should consider to drop and recreate the table.
You can find an example here
If you specify ?? INTEGER PRIMARY KEY or ?? INTEGER PRIMARY KEY AUTOINCREMENT then SQlite treats this in a specific way. That is ?? (by the looks of it ID in your case) is an alias for SQLite's rowid.
rowid if not specified when inserting a row will automatically be generated and is in general guaranteed to be unique and is normally incremented by one. However, it is not guaranteed to be incremented nor incremented by one.
If you specify AUTOINCREMENT (i.e. the latter of the two above) then the guarantee, is that a new rowid will be greater but not necessarily by 1.
There is a limit of 9223372036854775807 on the value of rowid. If AUTOINCREMENT is not used and this limit has been reached then an attempt will made to utilise free numbers (e.g. the rowid of rows that have been deleted). If AUTOINCREMENT is specified and the limit has been reached then an insert will fail with an SQLITE_FULL error.
As such, in your case the freed ID's from deleting rows will not be reused.
In short you should never rely upon the rowid (or an alias of it) column being a specific value, rather you should rely upon it just being a unique value purely for the purpose of uniquely identifying a row (and perhaps the fastest way of accessing a row).
You can, albeit it inadvisable, set rowid either by say INSERT INTO mytable (rowid, myothercolumn) VALUES(1, 'other data') or if ID has been used as an alias then INSERT INTO mytable (ID, myothercolumn)VALUES(1, 'other data').
If you really need the first row to be 1 and then 2 and so on then you could DROP the table and then recreate it rather then deleting all rows. e.g. DROP TABLE mytable, followed by CREATE TABLE mytable (ID INTEGER PRIMARY KEY, FIRSTNAME TEXT, LASTNAME TEXT). However, I'd suggest you will just end up with issues which will subsequently be far more complicated to determine and correct.
If you think about it, really what does Johnny Depp being 2 signify rather than Barack Obama being 2? If it is, for example, a popularity rating the surely you'd have some means of determining the popularity and input that directly rather than input it somewhere else to then be used to determine the insertion order and then do the inserts.
Much of the above is basically a summary of SQLite Autoincrement
As an example of unpredictability, a table was created with:-
CREATE TABLE mytable (ID INTEGER PRIMARY KEY, FIRSTNAME TEXT, LASTNAME TEXT)
A row was inserted using INSERT INTO mytable (ID, FIRSTNAME, LASTNAME) VALUES(9223372036854776000,'FRED','BLOGGS'). Note the use of 9223372036854776000 forces above the limit processing.
This was then followed by a number of INSERT INTO mytable(FIRSTNAME, LASTNAME) VALUES('????','????') inserts. Note! without ID, so using SQLITE's unique identifer determination (above the limit processinmg). The resultant table :-
MARY QUITECONTRARY was the 2nd row inserted,TOM SMITH the 3rd. The two RICHARD BURTON rows are an example of where the unique id could be essential for determining a specific row, both were also inserted without specifying the insertion order.
Note! if the above were tried but with AUTOINCREMENT specified, then the second insert, and any subsequent inserts, would fail with an SQLITE_FULL error.

After deleting a row in SQLite, _ID of a new entry is not consecutive

I use this method to delete a row in my sqlite db:
db.execSQL("delete from "+TABLE_NUMS+" where _ID = '" + this.rowID + "'");
and then I update the rest of Ids to make my entries consecutive:
db.execSQL("UPDATE "+TABLE_NUMS+" set _ID = (_ID - 1) WHERE _ID > "+this.rowID);
And it works fine, but when I add new entries to my DB, the ID of the new entries still add as if the deleted entries existed, say I have 10 rows with IDs starting from 1 to 10, and then I delete number 5 and 6, the rows become 1 to 8, but the new entry's ID will be 11. So my IDs sequence would be 1 to 8 and 11. How can I fix this?
SQLite keeps track of the largest ROWID that a table has ever held using the special SQLITE_SEQUENCE table. You cam modify that sequence as:
UPDATE SQLITE_SEQUENCE SET seq = this.ID -1 WHERE name = TABLE_NUMS
The same functionality is asked in this question.
The normal ROWID selection algorithm described above will generate
monotonically increasing unique ROWIDs as long as you never use the
maximum ROWID value and you never delete the entry in the table with
the largest ROWID. If you ever delete rows or if you ever create a row
with the maximum possible ROWID, then ROWIDs from previously deleted
rows might be reused when creating new rows and newly created ROWIDs
might not be in strictly ascending order.
http://www.sqlite.org/autoinc.html
This is how SQLite works.
If you really need to have the Ids consecutive don't use autoincrement.
Insert the ids yourself.
You can select MAX(_ID) first to get the last id (greatest value).
This is because you have autoincrement set on _ID when you created the table. So, every row you add will be given a number automatically unless you explicitly set it. If it is absolutely necessary that you need the _IDs in consecutive order, I recommend that you set it yourself instead of using autoincrement.
Here is how to reset it:
delete from your_table;
delete from sqlite_sequence where name='your_table';
This will delete all your data and reset the sequence.
SQLite keeps the largest ROWID in the special SQLITE_SEQUENCE table. You can update that table as:
db.execSQL("UPDATE SQLITE_SEQUENCE SET seq = 0 WHERE NAME = '"+TABLE_NAME+"'");
OR
delete that table as:
db.delete("SQLITE_SEQUENCE","NAME = ?",new String[]{TABLE_NAME});

Deleting in database?

I have a question about the databases in Android. I had created in my app a database. If I delete a record from database, for example the last one, and after that I insert a new record in database, the new record is not saved in database in the row where I deleted the other record. That row is empty. It is saved in the next row. Why? Should I do something?
I'm assuming you are talking about an sqlite DB?
If your rowid is a field declared using AUTOINCREMENT, then (from the docs) 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".
You can read about the autoincrement algorithm here: http://www.sqlite.org/autoinc.html
Note that you do NOT have to use AUTOINCREMENT to have your primary key auto select a rowid.

Categories

Resources