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

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.

Related

SQLite Autoincrement not inserting

I have an SQLite Database and when I insert the ID should be automaticly incrementet with AUTOINCREMENT.
But it is always null.
This is the create table
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE ausgaben (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, TAG text,DATUM text, AUSGABE text, MENGE text, KATEGORIE text)");
}
And this is how I insert data:
public boolean insertAusgabe(String tag, String datum, String ausgabe, String menge, String kategorie){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.putNull("id");
contentValues.put(AUSGABEN_TAG,tag);
contentValues.put(AUSGABEN_DATUM,datum);
contentValues.put(AUSGABEN_AUSGABE,ausgabe);
contentValues.put(AUSGABEN_MENGE,menge);
contentValues.put(AUSGABEN_KATEGORIE,kategorie);
db.insert(TABLE_NAME,null,contentValues);
return true;
}
If I understand right, this should work correctly.
But the database looks like this:
It would appear that you are expecting the id column to be null rather than a number.
If you code id INTEGER PRIMARY KEY NOT NULL AUTOINCREMENT (see note about AUTOINCREMENT below) then that column is a special column that is an alias of the rowid column (unless the table has been defined using WITHOUT ROWID).
The rowid column cannot be null and must be a integer value. If an attempt is made to insert a row where the value for the column is null (or not specified) then SQLite will assign an integer value (long for java). 1 if there are no rows in the table then 1 greater than the highest number used.
Hence why you have a sequence of numbers in the id column.
If, for example the table were defined using id INT PRIMARY KEY NOT NULL then, the id column IS NOT an alias of the rowid column. (AUTOINCREMENT can then not be used as it can only be used for an alias of the rowid column) Then none of the inserts would work as the value for the id column would be NULL which due to the coding of the NOT NULL constraint will result in a constraint conflict.
However if the column were defined using id INT PRIMARY KEY, then null values for the id would be allowed. Noting that coding PRIMARY KEY, implies a UNIQUE constraint, that is all values must be UNIQUE. SQLite considers all NULL values as being unique in comparison to each other.
So the last definition would allow what appears to be your expected result. However, what use would an indeterminate value be for the purpose of identifiyting a row? (that's rhetorical).
As such the result you initially obtained, is the more useful result. Even if not intended.
A note on AUTOINCREMENT
AUTOINCREMENT is very likely not needed, this specifies an extension of the rowid determination algorithm in that it
enforces the latest rowid value being greater than any existing or used rowid,
that is it relies upon another table, namely sqlite_sequence to record the highest allocated rowid and then it uses the higher of the highest existing rowid or the value stored for the table in the sqlite_sequence table.
With AUTOINCREMENT when the highest possible value (9223372036854775807) has been assigned and an attempt is made to insert a new row. Then an SQLITE_FULL error will result. Without, attempts are made to use an random unused value (e.g. if rows have been deleted).
With AUTOINCREMENT there is an overhead (something like 8-12% according to What are the overheads of using AUTOINCREMENT for SQLite on Android?).
NOTE
It should be noted that there is no gaurantee that the rowid, with or without the AUTOINCREMENT keyword will increase by 1. There are some situations where values may be skipped as per
Note that "monotonically increasing" does not imply that the ROWID always increases by exactly one. One is the usual increment. However, if an insert fails due to (for example) a uniqueness constraint, the ROWID of the failed insertion attempt might not be reused on subsequent inserts, resulting in gaps in the ROWID sequence. AUTOINCREMENT guarantees that automatically chosen ROWIDs will be increasing but not that they will be sequential.
SQLite Autoincrement
*In short it is not wise to have any expectation of the * id/rowid column to be anything other than a means of efficiently identifying a row.

Designing date orientated database sqlite

I'm new in sqlite. I've built database but based on query I was trying to solve for it (which was over-complicated), I was suggested to look into normalising database, which I did, but can't seem to find examples on database that would be orientated around dates like a diary, with lots of daily entries. I'm working on app that would help log in everyday what I've eaten, what exercise did I do, what activities I've done, what was my well-being, how many hours I've slept. I will be able to go back to any day in the past and see what I was up to, so it will have to look up all entries for that particular date.
So I understand I need separate tables for food type, exercise type, activities types, event types and I need main table "diary" which will log each time date and id referencing another table. So I'm wondering if in that diary table I can have date column, id column and lets say type column (which will differentiate which table does id column references) or should I rather have date column and column for each of the other tables ids, even though I will be logging only one type at the time?
Also, would indexing the date column be a good idea?
Or maybe there is a better way to design that database? Any suggestions will be appreciated.
So I understand I need separate tables for food type, exercise type,
activities types, event types
If normalising then perhaps consider a single table for all types with a column to indicate the type.
So I'm wondering if in that diary table I can have date column, id
column and lets say type column (which will differentiate which table
does id column references) or should I rather have date column and
column for each of the other tables ids, even though I will be logging
only one type at the time?
If you are logging and assuming human input (as opposed to automated) then it is highly likely that a timestamp would be sufficient to uniquely identify a row.
As such there would be little need for an id column(in theory).
Saying that SQLite, unless you specify WITHOUT ROWID (which you might consider, this may be of use in deciding:-Clustered Indexes and the WITHOUT ROWID Optimization ), automatically creates a unique row identifier column i.e ROWID.
If you code a column as columnname INTEGER PRIMARY KEY or columnname INTEGER PRIMARY KEY AUTOINCREMENT then columnname becomes an alias for ROWID, in which case the unique value will be provided, if you do not provide a value when inserting.
However, if you were to specify timestamp INTEGER PRIMARY KEY and provide the current date/time as a value for the column when inserting, the current date/time would be stored and would also be indexed (it would have to be unique (current date/time would very likely be)).
So I'd suggest that a log entry need only be something like CREATE TABLE log (timestamp INTEGER PRIMARY KEY, eventref INTEGER);, where eventref is a reference to the event type.
As _id is required at times e.g. for a CursorAdapter then you could specify the columns to be extracted as *, timestemp as _id (3 columns timestamp, eventref and _id (timestamp and _id would be identical))or timstemp as _id, * (3 columns but _id, timestamp and eventref) or timestamp as _id, eventref (2 columns _id and eventref).
So using this model as the basis would minimise columns and be indexed automatically.
An example
You may have the events table as :-
Along with log table as :-
A query such as SELECT * FROM log JOIN events WHERE eventref = _id would give:-
Note! made up timestamps for illustration purposes

How exactly SQLite database update primary key id?

Suppose I have a table contacts
id Name Contact_No
-----------------------------------------
1 abc 12345
2 lmn 56784
3 pqr 83654
4 uvw 17637
5 xyz 98345
If I delete row 3 from database, what would be the id of rows following the deleted row?
And if I update row 4, will it be given a new id or the id of row 4 will remain same after updating database?
What is the difference between autoincrement and autoincrement not null? Official documentation says that it will degrade the performance and database will work slow. Is it mandatory to write it along with integer primary key?
I have read many stackoverflow answers and also read SQLite Official Documentation but I couldn't get it.
Assuming id is the name of your INTEGER PRIMARY KEY column.
If you update a row, it will never change its id, since it is still the same row. (that's the whole point of update).
Regarding the creation of new ids, everything is in the doc your linked:
Relevant sections :
Without AUTOINCREMENT
On an INSERT, if the ROWID or INTEGER PRIMARY KEY column is not explicitly given a value, then it will be filled automatically with an unused integer, usually the one more than the largest ROWID currently in use.
There is no strict rule, it can be implementation dependent. Usually it will be equal to select max(id)+1. In you case 6, but if you delete row 5, the id 5 can be reused. (But don't rely on this).
With AUTOINCREMENT
If a column has the type INTEGER PRIMARY KEY AUTOINCREMENT (...) 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. If the table has never before contained any data, then a ROWID of 1 is used.
Adding NOT NULL to AUTOINCREMENT is therefore pointless.
In your case, the next id is 6, no matter how many rows you delete before that.
If you just use integer primary key then any insert will use the current maximum ROWID (for which id is effectively an alias) plus one. Thus deleting row 3 and inserting a new row will use 6. However, if you were to delete row 5 (leaving the maximum ROWID at 4) a newly-inserted row would get an id of 5.
If you care about id's not being reused, then you need autoincrement. The reason this is slower (and advised against unless you need it) is that the largest ever value is kept in an internal table. Inserts then have to read/update this internal table as part of their operation. If autoincrement was used, then an insert after deleting either 3 or 5 would create a row with id 6.
A normal update of row 4 would leave the id the same, unless you used insert or replace which effectively deletes the row and inserts a new one. Such an insert would follow the same rules as above.

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

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());

Android SQLite dilemma

I want to increase my integer primary key by 1 for every new entry in a specific table. I read that i could do that by using AUTOINCREMENT. On the other hand i found the note below:
Note that "monotonically increasing" does not imply that the ROWID always increases by exactly one. One is the usual increment. However, if an insert fails due to (for example) a uniqueness constraint, the ROWID of the failed insertion attempt might not be reused on subsequent inserts, resulting in gaps in the ROWID sequence. AUTOINCREMENT guarantees that automatically chosen ROWIDs will be increasing but not that they will be sequential.
So my question is, shall i use autoincrement to keep counting my rows in the table?
Use AUTOINCREMENT for increasing the primary key and a simple query to count the number of rows in the table. Don't use AUTOINCREMENT to count the number of rows.
SELECT COUNT(*) FROM table_name
You should count the number of rows using
SELECT Count(*) FROM tableName
For ensuring a unique id for your rows, you can use the autoIncrement function. That is its purpose and that is what it will do.
Usually there's no need to be perfectionist with your db key index - its important that it will be unique but in 99% of the times the consistency is not important.
AUTOINCREMENT ensure your key id will be unique and that's why you should use it.
of-course I don't know the reason you want a consistent key so there is a chance you do need it but
there's other aids for anything you would think of doing with a consistent id row
in Android - for counting and going through your table you can use cursors.

Categories

Resources