I'm working with Spring and Hibernate to develop web applications in Java. Let's assume that I have a table. When I delete some records from this table, sometimes I need to reset the value of the primary key field.
Let's say that I have 10 records in a table and I delete the last 5 records. Now, when I insert new records, the value of the primary key field should be started at 6
but it would start at 11
.
If I need to start the primary key value at 6
(maximum +1
) in MySql, I just need to execute the following SQL statement.
alter table table_name auto_increment=1;
This will automatically reset the value of auto_increment
to maximum + 1
value of that field (May conceptually be incorrect but it works).
In Oracle (10g), I'm using sequence
with the primary key. Is there a way in Oracle to reset the value of the sequence
to maximum + 1
value when some records are deleted from the database?
Best Solution
Reasons why you shouldn't reset the value if it's being used:
What happens if you have 20 records and delete records 5-10? You have a gap in the middle that re-setting the sequence will not solve. Sequences will never generate a gap free sequence of numbers, a perfect 1, 2 .. n.
If you call
.nextval
and don't use the value it's gone. Are you going to drop and re-create the sequence? If you start an insert and cancel it and Oracle rolls back what you've done those values are gone. If you setnocache
then you will have less gaps but at a cost of a hit to performance; is it worth it?Your cache should be set to the number of inserts you expect to do at any one time across all sessions to avoid any performance issues. Sequences are designed to provide a very quick, scalable way of creating a surrogate key without any locks etc not to re-generate the set of positive integers.
At the end of the day it shouldn't matter in the slightest. If you're relying on an unbroken sequence as the key of your table then you have a problem with your data rather than sequences.
Answering the question:
To actually answer your question you would need to:
Finding the maximum value means you'd need to re-create the sequence dynamically at the cost of another hit to performance.
If you try to insert something into your table whilst this is happening it will fail, and may invalidate any triggers or other objects which use the sequence:
As I say this is not recommended and you should just ignore any gaps.
Update - aka A Better Answer Thanks to Jeffrey Kemp:
Contrary to the documentation's recommendation there is, as Jeffrey Kemp suggested in the comments, a way to do this without dropping and re-creating the sequence.
Namely, by:
id
in your table and the current value of the sequence.The benefits of this are that the object still exists so and triggers, grants etc are still maintained. The downside, as I see it, is that if another session increments by this negative number at the same time as yours you can go back too far.
Here's a demonstration:
Set up the test:
Revert the sequence