Индекс оракула, если существует
Как вы отбрасываете индекс только в том случае, если он существует?
Кажется простым, но я нашел что-нибудь в сети.
Идея состоит в том, чтобы отказаться от нее, только если она существует, потому что если нет, у меня будет ошибка, и мой процесс остановится.
Я нашел это, чтобы найти, существует ли индекс:
select index_name
from user_indexes
where table_name = 'myTable'
and index_name='myIndexName'
Но я не знаю, как собрать его вместе с
DROP INDEX myIndexName
Ответы
Ответ 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;