SQLite: Reset primary key field error - sqlite

i am working with sqlite and i need to reset the auto increment values,
I found on StackOverflow:
SQLite Reset Primary Key Field
but when i do
delete from sqlite_sequence where name='my_table';
all I got is :
Error: no such table: sqlite_sequence
Did someone know the problem ?
I am on an iMac with sqlite3.
Thanks for help !
Have a nice day

There are two types of autoincrementing columns, ones declared as INTEGER PRIMARY KEY, and ones declared as INTEGER PRIMARY KEY AUTOINCREMENT.
Columns with AUTOINCREMENT have a record in the sqlite_sequence table, and can be reset with the above DELETE statement.
Plain INTEGER PRIMARY KEY columns are still autoincrementing, but derive the next value from the largest actual value in the table.
These can be simply reset by deleting all records from the data table itself.

I tested it on my own sqlite DB and it works fine.
See my Fiddle Demo.
Maybe in your case it could simply be a mistake of your spelling of your table name?
Or a misspelling on keyword sqlite_sequence maybe.

Related

Autoincrement in SQLite tables

I create a table, lets name it CUSTOMERS in SQLite:
CREATE TABLE "CUSTOMERS" (
"tel" INTEGER NOT NULL,
"customer" VARCHAR ,
);
When I see the table from a GUI (I use SQLite Manager from Firefox), I noticed that there is an extra column rowid which is working like auto-increment. My question is, in tables where I don't use a primary key should I specify a column like:
ROWID INTEGER PRIMARY KEY AUTOINCREMENT
If I execute this query PRAGMA table_info(CUSTOMERS); I get only the two columns tel,customer.
Sqlite usually adds a rowid automatically as #laato linked in the comments SqLite : ROWID
That can be removed, but does not need to be specified. So there is no need to add it to the Create Table.
The hidden rowid allows delete's to be targetted at a single row, bu
t if you are using the ROWID as a specific foreign key, it would be better to name a column explicitly. That will then become a synonym with the rowid.
You can see here, as it was commented in your question.
However, if you are in a dilemma what to choose between these options, SQLite recommends that you should not use AUTOINCREMENT attribute because:
The AUTOINCREMENT keyword imposes extra CPU, memory, disk space, and
disk I/O overhead and should be avoided if not strictly needed. It is
usually not needed.
More info you can read here.

I lost a table name in my sqlite_sequence table. How do I re-instate it?

It seems that when I revised a column definition (not the primary key column) in a table using the 'Edit Column' command on the Structure page under SQLite Manager, sqlite3 deleted that table name from its sqlite_sequence table. I tried to add it back in manually, but found that the seq number does not get updated on an addition into that lost table.
Does anyone know how to re-instate the lost table name?
The sqlite_sequence documentation says:
If the sqlite_sequence.seq value for an AUTOINCREMENT table is manually set to something other than an integer and there is a subsequent attempt to insert the or update the AUTOINCREMENT table, then the behavior is undefined.
However:
If the sqlite_sequence row for an AUTOINCREMENT table does not exist when the AUTOINCREMENT table is updated, then a new sqlite_sequence row is created.
So you should not add a 'fake' entry to sqlite_sequence, but you can change it if it exists.

autoincrement column remembers its last value in SQLite table

In one table I have a column that's an auto-incrementing primary key.
The problem is this scenario:
4 rows are inserted
those 4 are then subsequently deleted
insert a new row, and the the auto-increment column value is 5
How can I get this auto-increment column to have value of 1?
An SQLite Autoincrement field will increment forever.It will not replace the deleted value.It will replace deleted value only if it exists maximum possible value.See this . What you are trying to achieve is not possible using autoincrement field.You have to do it programtically.
Instead of using auto increment you can just use integer primary key it will work fine. Even if your row is deleted one by one, the next increment will be done properly. If you leave the integer primary key field empty, the max value of the row is taken and a 1 is added (it's like max(value)+1). It works fine for me.
if we have a primary which is autoincrement, the value will not be same even if you delete all the existing entries. It will continue from where it stopped on last insert. if you want the primary key to start from 1 again, you need to truncate the table or delete & recreate the table.
In SQLite "truncate" command is not valid. You can use a "Delete from tablename" and "vacuum tablename" to reset the primary key count to start from 1. Please make sure there is no "where" clause in delete command.

SQLITE: Unable to remove an unnamed primary key

I have a sqlite table that was originally created with:
PRIMARY KEY (`column`);
I now need to remove that primary key and create a new one. Creating a new one is easy, but removing the original seems to be the hard part. If I do
.indices tablename
I don't get the primary key. Some programs show the primary key as
Indexes: 1
[] PRIMARY
The index name is typically in the [].
Any ideas?
You can't.
PRAGMA INDEX_LIST('MyTable');
will give you a list of indices. This will include the automatically generated index for the primary key which will be called something like 'sqlite_autoindex_MyTable_1'.
But unfortunately you cannot drop this index...
sqlite> drop index sqlite_autoindex_MyTable_1;
SQL error: index associated with UNIQUE or PRIMARY KEY constraint cannot be dropped
All you can do is re-create the table without the primary key.
I the database glossary; a primary-key is a type of index where the index order is typically results in the physical ordering of the raw database records. That said any database engine that allows the primary key to be changed is likely reordering the database... so most do not and the operation is up to the programmer to create a script to rename the table and create a new one. So if you want to change the PK there is no magic SQL.
select * from sqlite_master;
table|x|x|2|CREATE TABLE x (a text, b text, primary key (`a`))
index|sqlite_autoindex_x_1|x|3|
You'll see that the second row returned from my quick hack has the index name in the second column, and the table name in the third. Try seeing if that name is anything useful.

Set start value for AUTOINCREMENT in SQLite

How can I set the start value for an AUTOINCREMENT field in SQLite?
From the SQLite web site:
SQLite keeps track of the largest ROWID that a table has ever held using the special SQLITE_SEQUENCE table. 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.
I tried this, and it works:
UPDATE SQLITE_SEQUENCE SET seq = <n> WHERE name = '<table>'
Where n+1 is the next ROWID you want and table is the table name.
Explicitly insert the value-1 into the table, then delete the row.
Edit: the next comment down, which discusses editing the SQLITE_SEQUENCE table directly is probably preferable: https://stackoverflow.com/a/692871/10093
I am using the below query which solves the problem when the sqlite_sequence does not have a record for the table (i.e. first record was not added yet to the table), otherwise it updates the sequence.
BEGIN TRANSACTION;
UPDATE sqlite_sequence SET seq = <n> WHERE name = '<table>';
INSERT INTO sqlite_sequence (name,seq) SELECT '<table>', <n> WHERE NOT EXISTS
(SELECT changes() AS change FROM sqlite_sequence WHERE change <> 0);
COMMIT;
One way to do it is to insert the first row specifying explicitly the row id you want to start with. SQLite will then insert row ids that are higher than the previous highest.
In solution with SQLITE_SEQUENCE table, the entry into this table seems to be added after the first insert into the table with the autoincrement column is added. In some cases this might cause troubles (i.e autoincrement still starts from 1, not from wanted value).
Just wanted to add a few notes to the very much appreciated answer from iTech:
The name column in sqlite_sequence is case sensitive. (Perhaps its only me, but coming from other databases I always assume that string comparison is case insensitive).
SQLite seems to be robust: if the number in sqlite_sequence is wrong and would lead to a duplicated rowid value, sqlite will use the next available number for the rowid (checked with sqlite 3.28)
Same is true if the row in sqlite_sequence gets deleted.
I used as suggested in a comment the "WHERE NOT EXISTS SELECT name from sqlite_sequence WHERE name = 'table'" instead of checking "changes()"
I tried this and it works good:
FOR INSERT
INSERT INTO sqlite_sequence (name, seq) VALUES ('<table name>', <value>)
TO UPDATE
UPDATE sqlite_sequence SET seq = <value> WHERE name= '<table name>'

Resources