Вопрос

I am getting a duplicate key error, DB2 SQL Error: SQLCODE=-803, SQLSTATE=23505, when I try to INSERT records. The primary key is one column, INTEGER 4, Generated, and it is the first column.

the insert looks like this: INSERT INTO SCHEMA.TABLE1 values (DEFAULT, ?, ?, ...)

It's my understanding that using the value DEFAULT will just let DB2 auto-generate the key at the time of insert, which is what I want. This works most of the time, but sometimes/randomly I get the duplicate key error. Thoughts?

More specifically, I'm running against DB2 9.7.0.3, using Scriptella to copy a bunch of records from one database to another. Sometimes I can process a bunch with no problems, other times I'll get the error right away, other times after 2 records, or 20 records, or 30 records, etc. Does not seem to be a pattern, nor is it the same record every time. If I change the data to copy 1 record instead of a bunch, sometimes I'll get the error one time, then it's fine the next time.

I thought maybe some other process was inserting records during my batch program, and creating keys at the same time. However, the tables I'm copying TO should not have any other users/processes trying to INSERT records during this same time frame, although there could be READS happening.

Edit: adding create info:

Create table SCHEMA.TABLE1 (
  SYSTEM_USER_KEY   INTEGER   NOT NULL
    generated by default as identity (start with 1  increment by 1  cache 20), 
  COL2...,
)

alter table SCHEMA.TABLE1
    add constraint SYSTEM_USER_SYSTEM_USER_KEY_IDX
    Primary Key (SYSTEM_USER_KEY);
Это было полезно?

Решение

You most likely have records in your table with IDs that are bigger then the next value in your identity sequence. To find out what the current value your sequence is about at, run the following query.

select s.nextcachefirstvalue-s.cache, s.nextcachefirstvalue-s.increment 
from syscat.COLIDENTATTRIBUTES as a inner join syscat.sequences as s on a.seqid=s.seqid 
where a.tabschema='SCHEMA' 
  and a.TABNAME='TABLE1' 
  and a.COLNAME='SYSTEM_USER_KEY'

So basically what happened is that somehow you got records in your table with ids that are bigger then the current last value of your identity sequence. So sooner or later these ids will collide with identity generated ids.

There are different reasons on how this could have happened. One possibility is that data was loaded which already contained values for the id column or that records were inserted with an actual value for the ID. Another option is that the identity sequence was reset to start at a lower value than the max id in the table.

Другие советы

Whatever the cause, you may also want the fix:

SELECT MAX(<primary_key_column>) FROM onsite.forms;
ALTER TABLE <table> ALTER COLUMN <primary_key_column> RESTART WITH <number from previous query + 1>;
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top