oracle 删除索引(如果存在)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2722630/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 02:32:55  来源:igfitidea点击:

oracle drop index if exists

oracleindexing

提问by CC.

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

回答by Samuel

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;
/

回答by UltraCommit

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;
/

回答by Will Marcouiller

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

在 Oracle 中,您不能混合使用 DDL 和 DML。为此,您需要使用EXECUTE IMMEDIATE语句来解决它。

So, first check for the existence of the index.

因此,首先检查索引是否存在。

Second, drop the index through the EXECUTE IMMEDIATE statement.

其次,通过 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;

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! =)

希望这可以帮助!=)

回答by Theis

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');

回答by Sofiane

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;