oracle删除索引(如果存在)
如何仅在索引存在时删除它 这看起来很简单,但我确实在网上找到了任何东西。 我们的想法是只有当它存在时才删除它,因为如果它不存在,我将有一个错误,我的进程将停止 我找到这个来查找索引是否存在:oracle删除索引(如果存在),oracle,indexing,Oracle,Indexing,如何仅在索引存在时删除它 这看起来很简单,但我确实在网上找到了任何东西。 我们的想法是只有当它存在时才删除它,因为如果它不存在,我将有一个错误,我的进程将停止 我找到这个来查找索引是否存在: select index_name from user_indexes where table_name = 'myTable' and index_name='myIndexName' 但我不知道如何把它和 DROP INDEX myIndexName 在Oracle中,不能同时使用DDL和DML。为
select index_name
from user_indexes
where table_name = 'myTable'
and index_name='myIndexName'
但我不知道如何把它和
DROP INDEX myIndexName
在Oracle中,不能同时使用DDL和DML。为了做到这一点,您需要围绕语句进行操作
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;
因此,首先检查索引是否存在
其次,通过executeimmediate语句删除索引
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;
这段代码是我脑子里想不出来的,你可能需要稍微修改一下,但这给了我一个想法
希望这有帮助!=) 不要检查是否存在。尝试删除,并在必要时捕获异常
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;
/
我创建了一个过程,以便可以多次调用它:
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');
我希望这会有所帮助。它是所有解决方案的组合:) 顺便说一下,谢谢你的帮助
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;
@塞缪尔的解决方案是最正确的。这是应该被接受的。当心DDL命令的隐式提交!!不管你喜欢与否,这一点都是肯定的。如果有必要,将其封装到一个自治事务中。没有直接解决方案的原因是不应该出现这种情况。这是一个配置管理问题。@APC这是理想世界和我们的世界之间的区别。在这种情况下,你不得不做一些“不应该做的”事情。有时候,这是因为以前有人做了一个错误的决定。有时,这是因为情况发生了变化,突然做出了一个在当时是好的选择,而不是坏的选择。在我看来,“它不应该发生”从来都不是遗漏某个特性的有效理由。这可能是在更重要的问题上分配资源的一个有效理由,但其他几种数据库技术提供了类似于
如果存在则删除,我很欣赏它的存在。当然,“删除索引”已经检查了索引的存在,所以您现在要做两次。这种技术引入了竞争条件。请考虑使用@塞缪尔提供的答案。我已经提醒用户,我接受的答案有竞争条件。我建议使用@Samuel提供的答案。我不能删除我的答案,因为它已在2010年被接受,而不是删除过程
您可以使用创建或替换过程
与接受的答案相比,这有什么优势,除了您可能可以将计数
替换为存在
?@jpmc26接受的答案具有竞争条件。索引可能被放在检查计数的行和执行立即数的行之间。@Samuel虽然这是一个有效点,但我希望人们不会有两个独立的命令试图同时对同一对象执行DDL。;)欢迎来到多线程世界:(很好的回答+1您忽略了这里的所有例外情况,这绝对不是一个好的做法。