oracle drop index if exists

一世执手 提交于 2019-12-18 11:17:42

问题


How do you drop an index only if it exists?

It seems simple but I did found anything on the net. The idea is to drop it only if it exists, because if not, I will have an error and my process stops.

I found this to find if the index exists:

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

But I don't know how to put it together with

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:


Don't check for existence. Try to drop, and capture the exception if necessary...

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:


In Oracle, you can't mix both DDL and DML. In order to do so, you need to work it around with the EXECUTE IMMEDIATE statement.

So, first check for the existence of the index.

Second, drop the index through the EXECUTE IMMEDIATE statement.

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;

This code is out the top of my head and you may need to fix it up a little, but this gives an idea.

Hope this helps! =)




回答4:


I made a procedure so it can be called several times:

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 ;

Now it can be called more than once:

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



回答5:


I hope this will help. It's a combination of all solution :) By the way thanks for the help !

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;


来源:https://stackoverflow.com/questions/2722630/oracle-drop-index-if-exists

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!