PL / SQL - хранимая процедура, которая переводит состояние индексов из НЕПРАВИЛЬНОГО в ВАЛИД - PullRequest
1 голос
/ 17 марта 2020

У меня есть курсор, который возвращает индексы от user_indexes с status = 'UNUSABLE' и печатает их на вкладке вывода:

DECLARE
    cur sys_refcursor;
BEGIN
    FOR iStat IN (SELECT INDEX_NAME FROM USER_INDEXES WHERE STATUS = 'UNUSABLE' ORDER BY INDEX_NAME) LOOP
            DBMS_OUTPUT.PUT_LINE('ALTER INDEX '||iStat.INDEX_NAME||' REBUILD');
    END LOOP;
END;

Вот некоторые из списка индексов, которые возвращают:

ALTER INDEX II_LKP_DRV_POLRIECUB_REA_MISC REBUILD;
ALTER INDEX IND1_CM_FACT_RVA_COMISION REBUILD;
ALTER INDEX IND2_CM_FACT_RVA_COMISION REBUILD;
ALTER INDEX INDX_SN_FACT_RECLA_ADJ_SINI REBUILD;

Я выполнил хранимую процедуру, чтобы сделать alter table для тех индексов, которые возвращены курсором (я использовал только 2 индекса для тестирования):

CREATE OR REPLACE PROCEDURE status_index
AS
cur sys_refcursor;

BEGIN
    FOR iStat IN (SELECT INDEX_NAME FROM USER_INDEXES WHERE INDEX_NAME IN ('II_LKP_DRV_POLRIECUB_REA_MISC', 'INDX_SN_FACT_RECLA_ADJ_SINI') AND STATUS = 'UNUSABLE' ORDER BY INDEX_NAME) LOOP
            'ALTER INDEX ' || iStat.INDEX_NAME || ' REBUILD';
    END LOOP;  
END;

Это работает, если я использую DBMS_OUTPUT.PUT_LINE, но если я использую ALTER INDEX во время запуска процедуры, выдается следующее сообщение об ошибке:

ORA-06550: line 2, column 5
PLS-00905: object ECCO_A.STATUS_INDEX is invalid
ORA-06550: line 2, column 5
PL/SQL: Statement ignored

Буду признателен, если кто-нибудь поможет мне исправить эту ошибку.

1 Ответ

3 голосов
/ 17 марта 2020

Оператор alter index является оператором языка определения данных. Он может работать только внутри блока / процедуры / функции DML (язык манипулирования данными), если вы используете Dynami c SQL. Ваш DML также действует как имплицитный коммит, который может вас удивить, если это один из цепочки исполняемых блоков кода.

BEGIN
    FOR iStat IN (SELECT INDEX_NAME FROM USER_INDEXES 
 WHERE INDEX_NAME IN ('II_LKP_DRV_POLRIECUB_REA_MISC', 
 'INDX_SN_FACT_RECLA_ADJ_SINI') 
 AND STATUS = 'UNUSABLE' 
 ORDER BY INDEX_NAME) 
LOOP
               EXECUTE IMMEDIATE 'ALTER INDEX ' || iStat.INDEX_NAME || ' REBUILD';
        END LOOP;  
    END;

См. здесь и здесь, Вы могли бы также подумать о том, что делает ваши индексы непригодными для использования в первую очередь, поскольку это может позволить вам не требовать этого обслуживания.

...