我有一个带有自动增量列的表,如下所示:
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,如何释放弹出的{在此插入脏话}锁?
最佳答案
SQL0913 没有创建锁 - 它报告锁存在。 ALTER TABLE 需要表上的排他锁才能重置 ID 号。一个表可以被另一个打开它的进程锁定,或者如果有未提交的行,它也可以被这个进程锁定。
使用该表还有另一个原因 - 软关闭(或伪关闭)。出于性能原因,DB2 for i 将游标保留在内存中,以便可以尽可能高效地重用它们。因此,即使您说 CLOSE CURSOR,DB2 也会将其保留在内存中。这些软关闭游标可以通过命令 ALCOBJ OBJ((SOMSCHEMA/SOMETABLE *FILE *EXCL)) WAIT(1) CONFLICT(*RQSRLS)
CONFLICT(*RQSRLS) 参数告诉 DB2 关闭所有软关闭光标。
所以问题的根源是 DB2 想要对表进行独占访问。这是一个设计问题,因为通常人们在工作日不会操纵表的结构。就 ID 号而言,这张表有时是父表,有时是子表。如果是这种情况,我可以建议您再次更改该表吗?
我认为如果您使用触发器而不是自动增量,实现可能会更好。在 INSERT 上触发触发器。如果提供了 ID,则不执行任何操作。如果未提供 ID,请选择 MAX(ID)+1 并将其用作提交到数据库的实际 ID 号。
关于sql - 在带有 PK 标识列的表中插入期间出现 AS400 DB2 重复键错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20190220/