oracle 索引存在则删除

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了oracle 索引存在则删除相关的知识,希望对你有一定的参考价值。

oracle:

drop index test_index;
create index test_index on sys_test(aaa) indextype is ctxsys.context;

执行删除操作时先判断索引是否存在,如果索引存在则删除,望给出正确SQL语句。PL/SQL。

Oracle sqlplus代码如下:

set serverout on;

declare
cnt number(10):=0;
begin
select count(*) into cnt from all_indexes where index_name='TEST_INDEX' and table_name='SYS_TEST';
if cnt=1 then
Execute immediate'drop index test_index';
Execute immediate'create index test_index on sys_test(aaa) indextype is ctxsys.context';
dbms_output.PUT_LINE('索引已经删除并重建');
else
dbms_output.PUT_LINE('索引不存在');
end if;
end;
参考技术A alter index test_index rebuild;--重建索引

select object_name from user_objects where object_type='INDEX'
--查出改用户下所有索引

还有什么不懂的联系我就行,qq即为账号

oracle 删除索引(如果存在)

【中文标题】oracle 删除索引(如果存在)【英文标题】:oracle drop index if exists 【发布时间】:2011-02-12 22:30:21 【问题描述】:

如果索引存在,如何删除它?

看起来很简单,但我确实在网上找到了任何东西。 我们的想法是仅在它存在时才删除它,因为如果不存在,我将出错并且我的进程将停止。

我发现这个是为了查找索引是否存在:

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

但是我不知道怎么搭配

DROP INDEX myIndexName

【问题讨论】:

@Samuel's 是最正确的解决方案。恕我直言,这是应该被接受的。 小心 DDL 命令的隐式提交!!那个 drop 提交,无论喜欢与否。如有必要,将其包装成一个自治事务。 之所以没有直截了当的解决方案,是因为不应该出现这种情况。这是一个配置管理问题。 @APC 这就是理想世界和我们的世界的区别。出现一些你必须做“不应该做”的事情的情况。有时,这是因为之前有人做出了错误的决定。有时,是因为形势发生了变化,突然做出了一个当时好的选择,变成了坏的选择。在我看来,“它不应该发生”是永远忽略某个功能的正当理由。这可能是为更重要的问题分配资源的正当理由,但其他几种数据库技术也提供了类似 DROP IF EXISTS 的功能,我很感激它的存在。 【参考方案1】:

不检查是否存在。尝试删除,并在必要时捕获异常...

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

【讨论】:

除了您可以将COUNT 替换为EXISTS 之外,这与已接受的答案相比有什么优势? @jpmc26 接受的答案有竞争条件。索引可能已在检查计数和立即执行的行之间删除。 @Samuel 虽然这是一个有效的观点,但我希望人们不会有 2 个独立的命令试图同时在同一个对象上执行 DDL。 ;) 欢迎来到多线程的世界。 :(很好的答案+1【参考方案2】:
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;
/

【讨论】:

当然,“DROP INDEX”已经检查索引是否存在,所以你现在要做两次。 这种技术引入了竞争条件。请考虑改用@Samuel 提供的答案。 我已提醒用户我接受的答案存在竞争条件。我建议改用@Samuel 提供的答案。我无法删除我的答案,因为它已在 2010 年被接受【参考方案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');

【讨论】:

你可以用DROP PROCEDURE代替CREATE OR REPLACE PROCEDURE【参考方案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;

【讨论】:

您在这里忽略了所有异常,这绝对不是一个好习惯。

以上是关于oracle 索引存在则删除的主要内容,如果未能解决你的问题,请参考以下文章

oracle创建表之前判断表是不是存在,如果存在则删除已有表

oracle创建表之前判断表是不是存在,如果存在则删除已有表

oracle创建表之前判断表是不是存在,如果存在则删除已有表

如果存在可在 SQL Server 2005 和 SQL Server Compact 3.5 中使用的索引,则删除该索引的脚本

Oracle数据库如何提高访问性能

如何解决Oracle“不能创建唯一索引,发现重复记录”问题