1

当我尝试插入记录时,出现重复键错误,DB2 SQL 错误:SQLCODE=-803,SQLSTATE=23505。主键是一列,INTEGER 4,Generated,它是第一列。

插入看起来像这样: INSERT INTO SCHEMA.TABLE1 values (DEFAULT, ?, ?, ...)

我的理解是,使用值 DEFAULT 只会让 DB2 在插入时自动生成密钥,这正是我想要的。这在大多数情况下都有效,但有时/随机我会收到重复键错误。想法?

更具体地说,我正在针对 DB2 9.7.0.3 运行,使用 Scriptella 将一堆记录从一个数据库复制到另一个数据库。有时我可以处理一堆没有问题,有时我会立即得到错误,有时在 2 条记录之后,或 20 条记录,或 30 条记录等。似乎不是模式,也不相同记录每一次。如果我将数据更改为复制 1 条记录而不是一堆,有时我会收到一次错误,然后下次就可以了。

我想也许其他一些过程正在我的批处理程序中插入记录,并同时创建密钥。但是,我要复制到的表不应该有任何其他用户/进程在同一时间范围内尝试插入记录,尽管可能会发生 READS。

编辑:添加创建信息:

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

2 回答 2

6

您的表中很可能有 ID 大于身份序列中下一个值的记录。要找出您的序列的当前值,请运行以下查询。

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'

所以基本上发生的事情是,不知何故,您在表中获得了 id 大于身份序列当前最后一个值的记录。所以这些 id 迟早会与身份生成的 id 发生冲突。

关于如何发生这种情况有不同的原因。一种可能性是加载的数据已经包含 id 列的值,或者插入的记录带有 ID 的实际值。另一种选择是身份序列被重置为从低于表中最大 id 的值开始。

于 2013-11-22T21:23:19.753 回答
1

无论是什么原因,您可能还需要修复:

SELECT MAX(<primary_key_column>) FROM onsite.forms;
ALTER TABLE <table> ALTER COLUMN <primary_key_column> RESTART WITH <number from previous query + 1>;
于 2015-01-03T04:02:24.183 回答