sql - 在带有 PK 标识列的表中插入期间出现 AS400 DB2 重复键错误

标签 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,如何释放弹出的{在此插入脏话}锁?

最佳答案

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/

相关文章:

mysql - SQL 返回父表中的所有行,其中条件与子表的另一个子表匹配

mysql - 查找日期为 2017 年的所有星期五

select - db2 查询以选择提取的第一行

oracle - 将 oracle 表复制到 DB2

java - 客户端访问 AS400 Java 包装器

mysql - 子查询值的总和

sql - 选择字符串不重复的行

SQL like 多字符

virtual-machine - AS400 模拟器或虚拟机

ruby - 是否可以通过 Web 应用程序的 Java 对话框提示用户输入密码?