使用PK标识列在表中插入期间AS400 DB2重复键错误

时间:2013-11-25 10:48:07

标签: sql db2 ibm-midrange

我有一个带有自动增量列的表,如下所示:

ALTER TABLE SOMESCHEMA.SOMETABLE 
    ALTER COLUMN ID 
        SET DATA TYPE INTEGER GENERATED BY DEFAULT 
        SET INCREMENT BY 1 
        SET NO ORDER 
        SET NO CYCLE 
        SET MINVALUE 1 
        SET MAXVALUE 2147483647 
        SET NO CACHE;

只要我让DBMS生成ID,一切正常,我可以通过以下方式获取生成的Id:

SELECT IDENTITY_VAL_LOCAL() FROM sysibm.sysdummy1

但有时我需要插入一个带有我选择ID的行,并且我遇到了麻烦。

假设我们在表格中有一行ID为1.我现在插入一个新行,手动分配的ID为2.
下次我尝试插入一个没有的新行预设ID我收到错误SQL0803“DUPLICATE KEY”。

我假设如果手动设置了行的Id,则该自动增量列的内部“NextId”字段不会自动更新。

所以我尝试用以下方法重置此字段:

ALTER TABLE SOMESCHEMA.SOMETABLE ALTER COLUMN ID RESTART WITH 3

但是这导致永久的表锁定,我不知道如何解锁。

如何让这种“混合模式”ID列工作?是否有可能让它像MySQL一样工作,DBMS会在手动ID插入时自动更新“NextID”?如果不是,如果我尝试重置NextId,如何释放弹出的{insert swear-word here}锁?

2 个答案:

答案 0 :(得分:3)

SQL0913没有创建锁 - 它报告存在锁。 ALTER TABLE需要对表进行独占锁定才能重置ID号。一个表可以被打开的另一个进程锁定,或者如果有未提交的行,它可以被此进程锁定。

该表正在使用中还有另一个原因 - 软关闭(或伪关闭)。出于性能原因,DB2 for i将游标保留在内存中,以便尽可能高效地重用它们。因此,即使您说CLOSE CURSOR,DB2也会将其保留在内存中。这些软关闭游标可以通过命令ALCOBJ OBJ((SOMSCHEMA/SOMETABLE *FILE *EXCL)) WAIT(1) CONFLICT(*RQSRLS)关闭.CONFLICT(* RQSRLS)参数告诉DB2关闭所有软关闭游标。

因此问题的根源是DB2希望对表进行独占访问。这是一种设计问题,因为通常一个人不会在工作日操纵表的结构。这听起来好像这个表有时是父母,有时候是儿童身份证。如果是这种情况,我可以建议您再次更改表格吗?

我认为如果使用触发器而不是自动增量,实现可能会更好。在INSERT上触发触发器。如果提供了ID,则不执行任何操作。如果未提供ID,则选择MAX(ID)+1并将其用作您提交给数据库的实际ID号。

答案 1 :(得分:0)

ALTER TABLE table_name ALTER COLUMN column_name RESTART WITH 99999;

修正了我的问题。 “99999”是下一个用于示例的ID