【小霸王】怪异ORA-01502(创建唯一约束却无唯一索引)

上一篇 / 下一篇  2008-05-14 11:02:15

我们都知道,唯一约束是基于唯一索引的,如果没有唯一索引,那么在建立唯一约束的时候会自动创建相应的唯一索引。而今天我在创建唯一约束以后,发生了一件怪异的事情。下面是过程描述。

因业务要求,要求在一表(test)上一列增加一个唯一约束,由于是在开发环境,数据量也很小,我采用了如下的方法来创建:

SQL> alter table test
  2    add constraint UK_ET_AIRSUP_USERS_supp_WW unique (air_supply_wangwang)
  3    using index
  4    tablespace TBS_ET_IND
  5    online
  6    compute statistics;

Table altered.

理论上按照这种方式,已经完全完成工作了。可是,后来测试人员测试的是,却告诉我发生了如下错误:

ORA-01502: index '.' or partition of such index is in unusable state

查询错误描述,可以很清楚的发现问题的原因:

[oracle@crmtest worksh]$ oerr ora 01502
01502, 00000, “index ‘%s.%s’ or partition of such index is in unusable state”
// MERGE: 1489 RENUMBERED TO 1502
// *Cause: An attempt has been made to access an index or index partition
// that has been marked unusable by a direct load or by a DDL
// operation
// *Action: DROP the specified index, or REBUILD the specified index, or
// REBUILD the unusable index partition

昨天都是没有问题,因此我就怀疑我今天这个唯一约束出了问题,查询了一下表的index:

SQL> select index_name,index_type,status from user_indexes where table_name = upper('test');

INDEX_NAME                     INDEX_TYPE                  STATUS
------------------------------ --------------------------- --------
PK_ET_AIRSUPPLY_USERS          NORMAL                      VALID
UK_ET_AIRSUPPLY_USERS_NICK     NORMAL                      VALID

怪异的事情发生了,怎么没有相应的唯一索引呢?确定看看唯一约束有没有什么问题:

SQL> alter table test
  2  modify constraint UK_ET_AIRSUP_USERS_SUPP_WW enable validate;

Table altered.

再看看结果如何:

SQL> select index_name,index_type,status from user_indexes where table_name = upper('test');

INDEX_NAME                     INDEX_TYPE                  STATUS
------------------------------ --------------------------- --------
PK_ET_AIRSUPPLY_USERS          NORMAL                      VALID
UK_ET_AIRSUPPLY_USERS_NICK     NORMAL                      VALID

SQL> delete from test t where t.id in ('1','2','3')
  2  ;
delete from test t where t.id in ('1','2','3')
*
ERROR at line 1:
ORA-01502: index '.' or partition of such index is in unusable state

还是不对。于是决定重建这个唯一约束:

SQL> select index_name,index_type,status from user_indexes where table_name = upper('test');

INDEX_NAME                     INDEX_TYPE                  STATUS
------------------------------ --------------------------- --------
PK_ET_AIRSUPPLY_USERS          NORMAL                      VALID
UK_ET_AIRSUPPLY_USERS_NICK     NORMAL                      VALID

SQL> alter table test
  2  drop constraint UK_ET_AIRSUP_USERS_SUPP_WW;

Table altered.

SQL> select index_name,index_type,status from user_indexes where table_name = upper('test');

INDEX_NAME                     INDEX_TYPE                  STATUS
------------------------------ --------------------------- --------
PK_ET_AIRSUPPLY_USERS          NORMAL                      VALID
UK_ET_AIRSUPPLY_USERS_NICK     NORMAL                      VALID

SQL> delete from test t where t.id in ('1','2','3');

0 rows deleted.

SQL> alter table test
  2    add constraint UK_ET_AIRSUP_USERS_supp_WW unique (air_supply_wangwang)
  3    using index
  4    tablespace TBS_ET_IND
  5    online
  6    compute statistics;

Table altered.

SQL> delete from test t where t.id in ('1','2','3');

0 rows deleted.

SQL> rollback;

Rollback complete.

SQL> select index_name,index_type,status from user_indexes where table_name = upper('test');

INDEX_NAME                     INDEX_TYPE                  STATUS
------------------------------ --------------------------- --------
PK_ET_AIRSUPPLY_USERS          NORMAL                      VALID
UK_ET_AIRSUPPLY_USERS_NICK     NORMAL                      VALID
UK_ET_AIRSUP_USERS_SUPP_WW     NORMAL                      VALID


SQL> select * from v$version;

BANNER
----------------------------------------------------------------
Oracle9i Enterprise Edition Release 9.2.0.6.0 - Production
PL/SQL Release 9.2.0.6.0 - Production
CORE    9.2.0.6.0       Production
TNS for Linux: Version 9.2.0.6.0 - Production
NLSRTL Version 9.2.0.6.0 - Production

这个时候问题已经解决。但是这个事件有点诡异,这个错误也无法重现,只是想提醒一下,可能会出现这种现象,虽然它几率很小。

为了避免此类错误的出现,最好的解决方法,至少在生产库上做操作,可以先自己手工创建唯一索引,然后在创建约束,这样就万无一失了。

--EOF--


TAG:

 

评分:0

我来说两句

显示全部

:loveliness: :handshake :victory: :funk: :time: :kiss: :call: :hug: :lol :'( :Q :L ;P :$ :P :o :@ :D :( :)

我的栏目

日历

« 2008-09-06  
 123456
78910111213
14151617181920
21222324252627
282930    

数据统计

  • 访问量: 12256
  • 日志数: 110
  • 建立时间: 2008-03-27
  • 更新时间: 2008-06-24

RSS订阅

Open Toolbar