DB2错误:SQL0204N" SQL160215110205990"是一个未定义的名称

时间:2016-02-16 07:04:44

标签: sql db2 sql-function

我的表格中有以下索引/唯一约束。

[ApiVersion1RoutePrefix("tests")]
public class TestController : ApiController
{


    [Route("PackageDropOffLocation/{}")]
    [HttpPut]
    [HttpPatch]
    public IHttpActionResult PackageDropOffLocation(HttpRequestMessage, PackageDropOffLocationRequest packageDropOffLocationRequest)
    {
        return null;

    }

    [Route("PackageOnBoard")]
    [HttpPut]
    [HttpPatch]
    public IHttpActionResult PackageBoarded(HttpRequestMessage requestMessage, PackageBoardedRequest packageBoardedRequest)
    {
        return null;
    }

}
  public class PackageBoardedRequest
{
    public string PackageId { get; set; }

}

  public class PackageDropOffLocationRequest
{
    public string Id { get; set; }
    public double Longitude { get; set; }
    public double Latitude { get; set; }

}

现在我在我的darabase上运行以下代码段。

 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  

当我第一次运行时,我得到了以下回应。

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   

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

此外,当我再次运行相同的代码段时,我收到了以下错误。

DB20000I  The SQL command completed successfully.

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

2 个答案:

答案 0 :(得分:0)

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

SYSCAT.INDEXES中的每个索引名称也不会引用约束。因此,每次使用SYSCAT.INDEXES中的名称运行DROP CONSTRAINT都不会返回成功。

答案 1 :(得分:0)

与约束和索引的其他众所周知的数据库相比,IBM DB2的行为略有不同。因此,让我详细解释您的问题的解决方案。

您有下表。


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自动生成的约束。

这是我们在表格中的两个唯一约束。

        UNIQUE (ENTITY_TYPE, TENANT_ID, ENTITY_LOCAL_USERSTORE, ENTITY_NAME),
        UNIQUE (PROVISIONING_CONFIG_ID, ENTITY_TYPE, ENTITY_VALUE)

通过运行以下查询,您可以找到唯一约束的自动生成的名称。对于唯一约束,constraintyp ='U',对于主键,它是'P'。 db2“从sysibm.systabconst中选择NAME,其中tbname ='IDP_PROVISIONING_ENTITY'和constraintyp ='U'”

NAME                                                                                                                           
--------
SQL160219074557840                                                                                                             
SQL160219074557920 

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

您可以运行以下查询以查看为IDP_PROVISIONING_ENTITY表创建的索引。 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表的索引名称。

您可以通过为上述查询添加where子句来找到需要删除的特定索引,如下所示。 db2“从SYSIBM.SYSINDEXES中选择名称,其中TBNAME ='IDP_PROVISIONING_ENTITY'和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“从SYSCAT.CONSTDEP中选择CONSTNAME,BNAME,其中TABNAME ='IDP_PROVISIONING_ENTITY'”

CONSTNAME                  BNAME
SQL160219074557790      SQL160219074557290
SQL160219074557840      SQL160219074557790
SQL160219074557920      SQL160219074557860

根据结果,您可以了解约束的名称。 因此,与索引名称“SQL160219074557860”关联的约束名称为“SQL160219074557920”。

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