问题产生背景
Oracle数据库中存在一张表A中一个列a,列类型为varchar2类型,代码处理推送文件后将处理数据存入数据库时,由于数据超长导致未将a列数据存入。为解决该问题,将A表中a列修改为CLOB类型,修改后发现A表所以失效,导致系统告警。
下列为修改A表a列类型代码
create tabe A_bak as select * from A;
-- 对改修字段数据进行备份
alter table A add a_bak varchar2(1024);
-- 将修改列数据清空(清原因查看varchar2改成CLOB注意事项)
update A set a_bak = a;
update A set a = null;
--将列类型从varchar2改成CLOB类型
alter table A modify a long;
alter table A modify a CLOB;
-- 恢复数据
update A set a = a_bak;
-- 删除备份列
alter table A drop cloumn a_bak;
脚本执行完成,再次使用索引时数据库返回: 问题: ORA-01502: 索引或这类索引的分区处于不可用状态。分析问题,发现修改完a列的类型后,该表索引失效。
问题产生原因
分析:
查看表索引状态
-- 查看这张表的索引状态
select index_name, status from user_indexes where table_name='A';
-- 查询结果:有两个个索引,其中有两个都失效了。
-- oracle索引的状态:
-- VALID:当前索引有效
-- N/A :分区索引 有效
-- UNUSABLE:索引失效
INDEX_NAME STATUS
------------------------- --------
SYS_IL0000013716C00001$$ VALID
a_index UNUSABLE
根据查看表索引状态发现存在两个索引,手动创建的索引已经处于失效状态,另外SYS_IL0000013716C00001$$索引是由修改成CLOB类型时,数据库自动创建的索引。
解决方案
对数据库表中索引进行重建
alter index a_index rebuild;
修改脚本
alter table A add a_bak CLOB;
update A set a_bak = a;
alter table A drop column a;
alter table A rename column a_bak to a;