DB2 error : SQL0204N "SQL160215110205990" is an undefined name

DB2 error : SQL0204N "SQL160215110205990" is an undefined name

我的 table 中有以下 indexes/unique 约束。

 INDNAME               COLNAMES  
 SQL160215110206240    +ID                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             
 SQL160215110206360    +ENTITY_TYPE+TENANT_ID+ENTITY_LOCAL_USERSTORE+ENTITY_NAME                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       
 SQL160215145445420    +ENTITY_TYPE+TENANT_ID+ENTITY_LOCAL_USERSTORE+ENTITY_NAME+PROVISIONING_CONFIG_ID  

现在我 运行 在我的 darabase 上跟踪代码段。

BEGIN 
 DECLARE v_rcount VARCHAR(128);
 DECLARE STMT VARCHAR(200); 
 select INDNAME into v_rcount from SYSCAT.INDEXES WHERE TABNAME='IDP_PROVISIONING_ENTITY' AND         COLNAMES='+ENTITY_TYPE+TENANT_ID+ENTITY_LOCAL_USERSTORE+ENTITY_NAME';  
 SET STMT = 'ALTER TABLE IDP_PROVISIONING_ENTITY DROP CONSTRAINT ' ||  v_rcount; 
 PREPARE S1 FROM STMT; 
 EXECUTE S1;
END   

当我第一次 运行 它时,我收到了以下回复。

DB20000I  The SQL command completed successfully.

但是当我列出 table 的索引时,我仍然像以前一样看到所有 3 个索引。

而且当我再次 运行 相同的代码段时,出现以下错误。

SQL0204N  "SQL160215110206360" is an undefined name.  SQLSTATE=42704

不仅是这个索引,如果我试图删除同一数据库中的任何其他索引,我也会遇到同样的错误。这是什么原因?我该如何解决这个问题?

此问题的原因是,我从 SYSCAT.INDEXES 获取名称。所以它是 returning INDEX 的名称。即使为每个唯一约束创建了一个 INDEX,索引的名称也可以与约束的名称不同。所以在这里我删除了约束,然后我检查了索引 table 是否已删除。这就是为什么在删除约束后我仍然可以看到相同的索引名称的原因。

此外,SYSCAT.INDEXES 中的每个索引名称都不会引用约束。所以每次我 运行 使用 SYSCAT.INDEXES 中的名称删除约束都不会 return 成功。

IBM DB2 在约束和索引方面的表现与其他知名数据库略有不同。所以让我详细解释一下你的问题的解决方案。

您有以下 table.


CREATE TABLE IDP_PROVISIONING_ENTITY (
            ID INTEGER NOT NULL,
            PROVISIONING_CONFIG_ID INTEGER NOT NULL,
            ENTITY_TYPE VARCHAR(255) NOT NULL,
            ENTITY_LOCAL_USERSTORE VARCHAR(255) NOT NULL,
            ENTITY_NAME VARCHAR(255) NOT NULL,
            ENTITY_VALUE VARCHAR(255) NOT NULL,
            TENANT_ID INTEGER NOT NULL,
            PRIMARY KEY (ID),
            UNIQUE (ENTITY_TYPE, TENANT_ID, ENTITY_LOCAL_USERSTORE, ENTITY_NAME),
            UNIQUE (PROVISIONING_CONFIG_ID, ENTITY_TYPE, ENTITY_VALUE),
            FOREIGN KEY (PROVISIONING_CONFIG_ID) REFERENCES IDP_PROVISIONING_CONFIG(ID) ON DELETE CASCADE)
/

它有一个主键和两个唯一约束。 DB2 将自动为这三个约束创建索引。

问题是,我们没有将约束定义为命名约束。因此,我们必须付出额外的努力才能找出由 DB2 自动生成的索引和约束的名称。

这是我们在 table.

中的两个独特约束
        UNIQUE (ENTITY_TYPE, TENANT_ID, ENTITY_LOCAL_USERSTORE, ENTITY_NAME),
        UNIQUE (PROVISIONING_CONFIG_ID, ENTITY_TYPE, ENTITY_VALUE)

您可以通过 运行以下查询找到唯一约束的自动生成名称。 constraintyp='U' 用于唯一约束,它是 'P' 用于主键。 db2 "select NAME from sysibm.systabconst where tbname='IDP_PROVISIONING_ENTITY' and constraintyp='U'"

NAME                                                                                                                           
--------
SQL160219074557840                                                                                                             
SQL160219074557920 

以上是我得到的结果。您将在数据库中获得不同的值,因为这些值是随机生成的。

您可以 运行 以下查询来查看为 IDP_PROVISIONING_ENTITY' table 创建的索引。 db2 "SELECT NAME, COLNAMES FROM SYSIBM.SYSINDEXES WHERE TBNAME='IDP_PROVISIONING_ENTITY'"

NAME                            COLNAMES
SQL160219074557290                +ID 
SQL160219074557790                +PROVISIONING_CONFIG_ID+ENTITY_TYPE+ENTITY_VALUE
SQL160219074557860                +ENTITY_TYPE+TENANT_ID+ENTITY_LOCAL_USERSTORE+ENTITY_NAME

现在我们知道了两个唯一约束的约束名称和 IDP_PROVISIONING_ENTITY table.

的索引名称

您可以通过为上述查询添加一个 where 子句来找到您需要删除的特定索引,如下所示。 db2 "SELECT NAME FROM SYSIBM.SYSINDEXES WHERE TBNAME='IDP_PROVISIONING_ENTITY' and COLNAMES='+ENTITY_TYPE+TENANT_ID+ENTITY_LOCAL_USERSTORE+ENTITY_NAME'"

NAME                                                  
----------
SQL160219074557860 

在 IBM DB2 中,您不能直接删除为约束(主键或唯一)生成的索引。为此,您需要删除也会删除索引的约束。

但问题是我们不知道与索引关联的唯一约束的名称是什么 "+ENTITY_TYPE+TENANT_ID+ENTITY_LOCAL_USERSTORE+ENTITY_NAME”。我们已经知道需要删除的索引名称是SQL160219074557860.

您可以通过运行以下查询找出哪个约束与哪个索引相关联。 db2 "select CONSTNAME, BNAME from SYSCAT.CONSTDEP where TABNAME = 'IDP_PROVISIONING_ENTITY'"

CONSTNAME                  BNAME
SQL160219074557790      SQL160219074557290
SQL160219074557840      SQL160219074557790
SQL160219074557920      SQL160219074557860

根据结果,您可以了解约束的名称。 所以与索引名称 "SQL160219074557860" 关联的约束名称是 "SQL160219074557920".

既然我们现在知道约束名称,我们就可以删除唯一约束。 db2 "ALTER TABLE IDP_PROVISIONING_ENTITY DROP UNIQUE SQL160219074557920" 这将删除约束以及为约束创建的索引。