文章
姚 鑫 · 十月 2 阅读大约需 6 分钟

第三十三章 SQL命令 DROP INDEX

第三十三章 SQL命令 DROP INDEX

删除索引。

大纲

DROP INDEX index-name [ON [TABLE] table-name]

DROP INDEX table-name.index-name

参数

  • index-name - 要删除的索引的名称。Index-name是名称的SQL版本,可以包括下划线和其他标点符号。它作为SQL映射名称列在表的Management Portal SQL Catalog Details中。
  • ON table-nameON TABLE table-name - 可选-与索引关联的表的名称。可以使用任一语法指定表名:第一个语法使用ON子句;TABLE关键字是可选的。第二个语法使用限定名称语法schema-name.table-name.index-name。表名可以是限定的(schema.table),也可以是非限定的(Table)。未限定的表名采用缺省模式名。如果完全省略表名, IRIS将删除找到的第一个与index-name匹配的索引,如下所述。

描述

DROP INDEX语句从表定义中删除索引。可以使用DROP INDEX删除标准索引、位图索引或位片索引。通过删除相应的唯一索引,可以使用DROP INDEX删除唯一约束或主键约束。不能使用DROP INDEX删除位图范围索引或主地图(数据/主)IDKEY索引。

可能出于以下任一原因希望删除索引:
- 打算对表执行大量的INSERTUPDATEDELETE操作。可以对操作使用%noindex选项,而不是接受让这些操作中的每个操作都写入索引的性能开销。或者,在某些情况下,可能更可取的做法是删除索引,对数据库执行批量更改,然后重新创建索引并填充它。
- 不用于查询操作的字段或字段组合存在索引。在这种情况下,维护索引的性能开销可能不值得。
- 现在包含大量重复数据的字段或字段组合存在索引。在这种情况下,查询性能的最小收益可能不值得。

如果表中有数据,则不能删除IDKEY索引。尝试这样做会生成SQLCODE-325错误。

权限与锁

DROP INDEX命令是特权操作。用户必须具有%ALTER_TABLE管理权限才能执行DROP INDEX。否则将导致%msg用户‘name’没有%ALTER_TABLE权限的SQLCODE-99错误。如果拥有适当的授予权限,则可以使用GRANT命令将%ALTER_TABLE权限分配给用户或角色。管理权限是特定于命名空间的。

用户必须对指定表拥有%ALTER特权。如果用户是表的所有者(创建者),则会自动授予该用户对该表的%ALTER权限。否则,必须授予用户对该表的%ALTER特权。否则将导致SQLCODE-99错误,因为%msg用户‘name’没有更改‘Schema.TableName’的表定义所需的%ALTER特权。可以通过调用%CHECKPRIV命令来确定当前用户是否具有%ALTER特权。可以使用GRANT命令将%ALTER权限分配给指定表。

  • 不能对从持久类投影的表使用DROP INDEX,除非表类定义包括[DdlAllowed]。否则,操作将失败,并出现SQLCODE-300错误,同时未为类‘Schema.tablename’启用%msg DDL
  • DROP INDEX不能用于从部署的持久类投射的表。此操作失败,并出现SQLCODE-400错误,并显示%msg Unable to Execute DDL以修改已部署的类:‘classname’

DROP INDEX语句获取对table-name的表级锁。这可以防止其他进程修改表的数据。此锁在DROP INDEX操作结束时自动释放。

索引名称

当指定索引名来创建索引时,系统会通过剔除所有标点符号来生成相应的类索引名;它会将在类中指定的索引名保留为索引的SqlName值(SQL映射名称)。指定要删除索引的索引名时,需要指定包含标点符号的名称,标点符号将作为SQL映射名称在表的管理门户SQL目录详细资料中列出。例如,为唯一约束(MyTable_UNIQUE2)指定生成的SQL映射名称,而不是为索引名称(MYTABLEUNIQUE2)指定。此索引名称不区分大小写。

表名

可以使用DROP INDEX语法FORM指定与索引关联的表:

  • INDEX-NAME ON TABLE语法:指定表名称是可选的。如果省略, IRIS将在命名空间中的所有类中搜索相应的索引。

  • Table-name.index-name语法:需要指定表名。

在这两种语法中,表名可以是非限定的(Table),也可以是限定的(schema.table)。如果省略架构名称,则使用默认架构名称。

如果DROP INDEX没有指定表名, IRIS会在所有索引中搜索与索引名匹配的索引名SqlName,或者与索引名匹配的索引名SqlName,以查找没有为索引指定SQlname的索引。如果IRIS在任何类中都找不到匹配的索引,就会产生一个SQLCODE -333错误,表明不存在这样的索引。如果 IRIS找到多个匹配的索引,DROP INDEX无法确定要删除哪个索引;它会发出SQLCODE -334错误:“索引名称不明确。在多个表中找到索引。IRIS中的索引名称在每个命名空间中不是唯一的。

不存在的索引

默认情况下,如果尝试删除不存在的索引,DROP INDEX会默认发出SQLCODE-333错误。要确定当前设置,请调用$SYSTEM.SQL.CurrentSettings(),它显示一个允许DDL丢弃不存在的索引设置。默认值为0(“否”)。这是推荐的设置。如果设置为1(“是”),则不存在索引的DROP INDEX不执行任何操作,也不发出错误消息。

在管理门户、系统管理、配置、SQL和对象设置中,通过选中忽略冗余DDL语句复选框,可以在系统范围内设置此选项(以及其他类似的创建、更改和删除选项)。

表名

如果指定可选的table-name,则它必须与现有表相对应。

  • 如果指定的表名不存在, IRIS将发出SQLCODE-30错误,并将%msg设置为表‘SQLUser.tname’不存在。
  • 如果指定的表名称存在,但没有名为index-name的索引, IRIS将发出SQLCODE-333错误,并将%msg设置为尝试删除表SQLUSER.TNAME上的索引‘MyIndex’-未找到索引。
  • 如果指定的表名是视图, IRIS将发出SQLCODE-333错误,并将%msg设置为尝试删除视图SQLUSER.VNAME上的索引‘EmpSalaryIndex’失败。索引仅支持表,不支持视图。

示例

第一个示例创建名为Employee的表,本节的所有示例都使用该表。

下面的嵌入式SQL示例创建一个名为“EmpSalaryIndex”的索引,然后删除它。
注意,这里DROP INDEX没有指定与索引关联的表;
它假设“EmpSalaryIndex”是这个名称空间中的唯一索引名称。

ClassMethod DropIndex()
{
    &sql(
        CREATE TABLE Employee 
        (
            EMPNUM     INT NOT NULL,
            NAMELAST   CHAR(30) NOT NULL,
            NAMEFIRST  CHAR(30) NOT NULL,
            STARTDATE  TIMESTAMP,
            SALARY     MONEY,
            ACCRUEDVACATION   INT,
            ACCRUEDSICKLEAVE  INT,
            CONSTRAINT EMPLOYEEPK PRIMARY KEY (EMPNUM)
        )
    )
    w !,"SQLCODE = ",SQLCODE," 创建表"
    &sql(
        CREATE INDEX EmpSalaryIndex
        ON TABLE Employee
        (
            Namelast,Salary
        )
    )
    w !,"SQLCODE=",SQLCODE," 创建索引"

    n SQLCODE ,%msg
    &sql(
        DROP INDEX EmpSalaryIndex
    )
    w !,"SQLCODE=",SQLCODE," 删除索引"
    if (SQLCODE '=0 ) { 
        w !,"message",%msg
    }
}

下面的嵌入式SQL示例使用ON table子句指定与要删除的索引相关联的表:

/// d ##class(PHA.TEST.SQLCommand).DropIndex1()
ClassMethod DropIndex1()
{
    &sql(CREATE INDEX EmpVacaIndex
        ON TABLE Employee
        (
            NameLast,AccruedVacation
        )
    )
    w !,"SQLCODE=",SQLCODE," 创建索引"

    &sql(DROP INDEX EmpVacaIndex ON TABLE Employee)
    w !,"SQLCODE=",SQLCODE," 删除索引"
}

下面的嵌入式SQL示例使用限定名语法指定了与要删除的索引相关联的表:

ClassMethod DropIndex2()
{
    &sql(CREATE INDEX EmpSickIndex
        ON TABLE Employee
        (
            NameLast,AccruedSickLeave
        )
    )
        w !,"SQLCODE=",SQLCODE," 创建索引"

    &sql(DROP INDEX Employee.EmpSickIndex)
    w !,"SQLCODE=",SQLCODE," 删除索引"
}

下面的命令删除一个不存在的索引。
它生成SQLCODE -333错误:

DROP INDEX PeopleIndex ON TABLE Employee
00
1 0 0 7
Log in or sign up to continue