怪异ORA-01502,创建唯一约束却无唯一索引
我们都知道,唯一约束是基于唯一索引的,如果没有唯一索引,那么在建立唯一约束的时候会自动创建相应的唯一索引。而今天我在创建唯一约束以后,发生了一件怪异的事情。
下面是过程描述。
因业务要求,要求在一表(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
这个时候问题已经解决。但是这个事件有点诡异,这个错误也无法重现,只是想提醒一下,可能会出现这种现象,虽然它几率很小。
为了避免此类错误的出现,最好的解决方法,至少在生产库上做操作,可以先自己手工创建唯一索引,然后在创建约束,这样就万无一失了。
扫一扫订阅我的微信号:IT技术博客大学习
- 作者:小霸王 来源: ilonng
- 标签: ORA-01502 唯一索引 唯一约束
- 发布时间:2009-10-12 10:11:17
- [46] 界面设计速成
- [42] Oracle MTS模式下 进程地址与会话信
- [41] 视觉调整-设计师 vs. 逻辑
- [40] IOS安全–浅谈关于IOS加固的几种方法
- [39] android 开发入门
- [39] 图书馆的世界纪录
- [38] 【社会化设计】自我(self)部分――欢迎区
- [38] 如何拿下简短的域名
- [37] 程序员技术练级攻略
- [34] 读书笔记-壹百度:百度十年千倍的29条法则