For some reason, people in the past have inserted data without using sequence.NEXTVAL. So when I go to use sequence.NEXTVAL in order to populate a table, I get a PK violation, since that number is already in use in the table.
How can I update the next value so that it is usable? Right now, I'm just inserting over and over until it's successful (INSERT INTO tbl (pk) VALUES (sequence.NEXTVAL)
), and that syncs up the nextval.
With oracle 10.2g:
will set the current sequence value to the max(pk) of your table (i.e. the next call to NEXTVAL will give you the right result); if you use Toad, press F5 to run the statement, not F9, which pages the output (thus stopping the increment after, usually, 500 rows). Good side: this solution is only DML, not DDL. Only SQL and no PL-SQL. Bad side : this solution prints max(pk) rows of output, i.e. is usually slower than the ALTER SEQUENCE solution.
If you can count on having a period of time where the table is in a stable state with no new inserts going on, this should do it (untested):
This enables you to get the sequence back in sync with the table, without dropping/recreating/re-granting the sequence. It also uses no DDL, so no implicit commits are performed. Of course, you're going to have to hunt down and slap the folks who insist on not using the sequence to populate the column...
You can temporarily increase the cache size and do one dummy select and then reset the cache size back to 1. So for example
In my case I have a sequence called
PS_LOG_SEQ
which had aLAST_NUMBER = 3920
.I then imported some data from
PROD
to my local machine and inserted into thePS_LOG
table. Production data had more than20000
rows with the latest LOG_ID (primary key) being 20070. After importing I tried to insert new rows in this table but when saving I got an exception like this one:Surely this has to do with the Sequence
PS_LOG_SEQ
associated with thePS_LOG
table. TheLAST_NUMBER
was colliding with data I imported which had already used the next ID value from thePS_LOG_SEQ
.To solve that I used this command to update the sequence to the latest \
max(LOG_ID)
+ 1:This command reset the
LAST_NUMBER
value and I could then insert new rows into the table. No more collision. :)Note: this
alter sequence
command is new in Oracle 12c.These two procedures let me reset the sequence and reset the sequence based on data in a table (apologies for the coding conventions used by this client):