Невозможно отключить индекс во время процедуры PL / SQL - PullRequest
4 голосов
/ 12 мая 2010

Я написал процедуру PL / SQL, которая выиграла бы, если бы индексы сначала были отключены, а затем перестроены после завершения. существующий поток предлагает такой подход:

alter session set skip_unusable_indexes = true;

alter index your_index unusable;

[сделать импорт]

alter index your_index rebuild;

Однако в первом операторе alter index появляется следующая ошибка:

SQL Error: ORA-14048: a partition maintenance operation may not be combined with other operations
ORA-06512: [...]
14048. 00000 -  "a partition maintenance operation may not be combined with other operations"
*Cause:    ALTER TABLE or ALTER INDEX statement attempted to combine
           a partition maintenance operation (e.g. MOVE PARTITION) with some
           other operation (e.g. ADD PARTITION or PCTFREE which is illegal
*Action:   Ensure that a partition maintenance operation is the sole
           operation specified in ALTER TABLE or ALTER INDEX statement;
           operations other than those dealing with partitions,
           default attributes of partitioned tables/indices or
           specifying that a table be renamed (ALTER TABLE RENAME) may be
           combined at will

Индекс проблемы определяется так:

CREATE INDEX A11_IX1 ON STREETS ("SHAPE")
  INDEXTYPE IS "SDE"."ST_SPATIAL_INDEX" PARAMETERS
  ('ST_GRIDS=890,8010,72090 ST_SRID=2');

Это пользовательский тип индекса от стороннего поставщика, который вызывает хроническое снижение производительности во время операций обновления / вставки / удаления большого объема.

Есть предложения о том, как обойти эту ошибку? Кстати, эта ошибка возникает только внутри блока PL / SQL.

Редактировать: Вот процедура полностью:

procedure disable_indexes (
  tbl_name in varchar2
) as
  stmt varchar2(200);
  cursor curs(v_tbl_name in varchar2) is
    select 'alter index ' || index_name || ' unusable;' as ddl_stmt
    from user_indexes
    where upper(table_owner) = upper(user)
    and upper(table_name) = upper(v_tbl_name)
    and ityp_name in ('CTXCAT', 'ST_SPATIAL_INDEX');
begin
  for r_curs in curs(tbl_name) loop
    dbms_output.put_line(r_curs.ddl_stmt);
    execute immediate r_curs.ddl_stmt;
  end loop;
end;

Ответы [ 2 ]

5 голосов
/ 12 мая 2010

Если это действительно ваш код, а не перезапись псевдокода, удалите ; в конце вашего оператора в переменной stmt (в противном случае вы столкнетесь с ORA-00911: invalid character во время выполнения)

Теперь, если ваш процесс работает вручную, вы сможете настроить его на execute immediate в процедуре. Убедитесь, что это не проблема роли (см. Эту статью Тома Кайта ), введя SET ROLE NONE перед выполнением команд вручную.

0 голосов
/ 12 мая 2010

Вы пытались выполнить DROP INDEX до, а затем воссоздать его после?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...