如题,在ORACLE中自动新增删除分区以后,会报出ora-01502的错误。sql
首先,问题的缘由是在于进行表结构修改后,索引失效。问题解决有以下几个方式:oop
一、手动查询重建测试
(1)先查询失效索引,语句为:ui
select index_name ,status from user_indexes where Status = 'UNUSABLE' ;
(2)重建索引,语句为: spa
alter index xxx rebuild;
手动操做有个快捷的方式,能够将上面的步骤合成为一个查询语句: code
select 'alter index ' || index_name || ' rebuild;' from user_indexes where Status = 'UNUSABLE' ;
这样直接复制查询出来的语句手动执行便可。
索引
二、将上面的手动操做作成存储过程执行的“只能自动”table
(1)建立重建索引的存储过程,语句以下:class
create or replace procedure p_rebuild_all_index (tablespace_name in varchar2,--这里是表空间名,若是不改变表空间,能够传入null only_unusable in boolean) --是否仅对无效的索引操做 as sqlt varchar(200); begin --只取非临时索引 for idx in (select index_name, tablespace_name, status from user_indexes where temporary = 'N') loop --若是是如重建无效的索引,且当索引不是无效时,则跳过 if only_unusable = true and idx.status <> 'UNUSABLE' then goto continue; end if; if (tablespace_name is null) or idx.status = 'UNUSABLE' then --若是没有指定表空间,或索引无效,则在原表空间重建 sqlt := 'alter index ' || idx.index_name || ' rebuild '; elsif upper(tablespace_name) <> idx.tablespace_name then --若是指定的不一样的表空间,则在指定表空间待建索引 sqlt := 'alter index ' || idx.index_name || ' rebuild tablespace ' || tablespace_name; else --若是表空间相同,则跳过 goto continue; end if; dbms_output.put_line(idx.index_name); EXECUTE IMMEDIATE sqlt; <<continue>> null; end loop; end;
(2) 建立执行重建的存储过程select
CREATE OR REPLACE PROCEDURE EXEC_REBUILD_PROC AS v_err_num NUMBER; --ORA错误号 v_err_msg VARCHAR2(100); --错误描述 BEGIN --10表明建立10天的分区,tablespace表明表空间名 p_rebuild_all_index(NULL,true); COMMIT; EXCEPTION WHEN OTHERS THEN v_err_num := SQLCODE; v_err_msg := SUBSTR(SQLERRM, 1, 100); dbms_output.put_line('EXEC_REBUILD_PROC执行出现异常,错误码='|| v_err_num || '错误描述=' || v_err_msg); END EXEC_REBUILD_PROC;
如此便可。以上方式均已测试可用。