如果不存在则创建索引

Create index if not exist

全部,

SQL> SELECT 1 FROM all_indexes WHERE table_name = UPPER( 'abcatcol' ) AND index_name = UPPER( 'abcatcol_tnam_ownr_cnam' );

no rows selected

SQL> CREATE INDEX abcatcol_tnam_ownr_cnam ON abcatcol(abc_tnam, abc_ownr, abc_cnam);
CREATE INDEX abcatcol_tnam_ownr_cnam ON abcatcol(abc_tnam, abc_ownr, abc_cnam)
                                                 *
ERROR at line 1:
ORA-01408: such column list already indexed


SQL> SELECT 1 FROM all_indexes WHERE table_name = UPPER( 'abcatcol' );

         1
----------
         1

SQL> SELECT index_name FROM all_indexes WHERE table_name = UPPER( 'abcatcol' );

INDEX_NAME
------------------------------
SYS_C007087

SQL >

我错过了什么?为什么我不能创建索引?

编辑:

SQL> select index_name, listagg(column_name, ', ') within group(order by 1)-- over(partition by index_name)
  2    from dba_ind_columns
  3   where table_name = 'ABCATCOL'
  4   group by index_name;

INDEX_NAME
------------------------------
LISTAGG(COLUMN_NAME,',')WITHINGROUP(ORDERBY1)--OVER(PARTITIONBYINDEX_NAME)
--------------------------------------------------------------------------------
SYS_C007087
ABC_CNAM, ABC_OWNR, ABC_TNAM


SQL> SELECT index_name FROM all_indexes WHERE table_name = UPPER( 'abcatcol' );

INDEX_NAME
------------------------------
SYS_C007087

SQL>

编辑 2:

建议的问题使用 PL/SQL。我想了解如何使用标准 SQL 以及为什么我的查询无法按预期工作。

编辑 3:

这是 table 定义:

CREATE TABLE abcatcol(abc_tnam char(129) NOT NULL, abc_tid integer, abc_ownr char(129) NOT NULL, abc_cnam char(129) NOT NULL, abc_cid smallint, abc_labl char(254), abc_lpos smallint, abc_hdr char(254), abc_hpos smallint, abc_itfy smallint, abc_mask char(31), abc_case smallint, abc_hght smallint, abc_wdth smallint, abc_ptrn char(31), abc_bmap char(1), abc_init char(254), abc_cmnt char(254), abc_edit char(31), abc_tag char(254), PRIMARY KEY( abc_tnam, abc_ownr, abc_cnam ));

所以我想因为那些字段是 PK Otacle 的一部分已经建立了索引,对吧?

您正在按名称查找索引,而 oracle 告诉您这组列已被索引。

这意味着该列集上已经有一个具有另一个名称的索引。

您需要检查 dba_ind_columns table 以获取该列集上的索引名称

更新。这是帮助您找到索引列的查询

select index_name, listagg(column_name, ', ') within group(order by 1)-- over(partition by index_name)
  from dba_ind_columns
 where table_name = 'TABLE_NAME'
 group by index_name;