Подтвердить что ты не робот

Индекс оракула, если существует

Как вы отбрасываете индекс только в том случае, если он существует?

Кажется простым, но я нашел что-нибудь в сети. Идея состоит в том, чтобы отказаться от нее, только если она существует, потому что если нет, у меня будет ошибка, и мой процесс остановится.

Я нашел это, чтобы найти, существует ли индекс:

select index_name
from user_indexes
where table_name = 'myTable'
and index_name='myIndexName'

Но я не знаю, как собрать его вместе с

DROP INDEX myIndexName
4b9b3361

Ответ 1

DECLARE
   COUNT_INDEXES   INTEGER;
BEGIN
   SELECT COUNT ( * )
     INTO COUNT_INDEXES
     FROM USER_INDEXES
    WHERE INDEX_NAME = 'myIndexName';
   -- Edited by UltraCommit, October 1st, 2019
   -- Accepted answer has a race condition.
   -- The index could have been dropped between the line that checks the count
   -- and the execute immediate
   IF COUNT_INDEXES > 0
   THEN
      EXECUTE IMMEDIATE 'DROP INDEX myIndexName';
   END IF;
END;
/

Ответ 2

Не проверяйте существование. Попробуйте сбросить и при необходимости перехватить исключение...

DECLARE
   index_not_exists EXCEPTION;
   PRAGMA EXCEPTION_INIT (index_not_exists, -1418);
BEGIN
   EXECUTE IMMEDIATE 'drop index foo';
EXCEPTION
   WHEN index_not_exists
   THEN
      NULL;
END;
/

Ответ 3

В Oracle вы не можете смешивать DDL и DML. Чтобы сделать это, вам нужно выполнить его с помощью EXECUTE IMMEDIATE.

Итак, сначала проверьте наличие индекса.

Во-вторых, отбросьте индекс через инструкцию EXECUTE IMMEDIATE.

DECLARE v_Exists NUMBER;

BEGIN
    v_Exists := 0;

    SELECT 1 INTO v_Exists
        FROM USER_INDEXES
        WHERE TABLE_NAME LIKE 'myTable'
            AND INDEX_NAME LIKE 'myIndexName'

    IF v_Exists = 1 THEN
        EXECUTE IMMEDIATE "DROP INDEX myIndexName"
    ENDIF;

    EXCEPTION
        WHEN OTHERS THEN
            NULL;
END;

Этот код выходит из моей головы, и вам может понадобиться немного исправить его, но это дает представление.

Надеюсь, это поможет! =)

Ответ 4

Я сделал процедуру, чтобы ее можно было вызвать несколько раз:

DELIMITER €€
DROP PROCEDURE IF EXISTS ClearIndex€€
CREATE PROCEDURE ClearIndex(IN var_index VARCHAR(255),IN var_table VARCHAR(255))
BEGIN
    SET @temp = concat('DROP INDEX ', var_index, ' ON ', var_table);
    PREPARE stm1 FROM @temp;
    BEGIN
        DECLARE CONTINUE HANDLER FOR 1091 SELECT concat('Index ', var_index,' did not exist in ',var_table,', but was handled') AS 'INFO';
            EXECUTE stm1;
    END;
END €€
DELIMITER ;

Теперь его можно вызвать более одного раза:

CALL ClearIndex('employees_no_index','employees');
CALL ClearIndex('salaries_no_index','salaries');
CALL ClearIndex('titles_no_index','titles');

Ответ 5

Надеюсь, это поможет. Это комбинация всего решения:) Кстати спасибо за помощь!

CREATE OR REPLACE PROCEDURE CLEAR_INDEX(INDEX_NAME IN VARCHAR2) AS
BEGIN
    EXECUTE IMMEDIATE 'drop index ' || INDEX_NAME;
EXCEPTION
    WHEN OTHERS THEN
        NULL;
END CLEAR_INDEX;