我想动态重命名索引。
背景故事:如果基表具有主键,Oracle会在物化视图上自动创建索引(我认为?)。每次删除和创建MV时,该索引的名称都会更改。我想重命名该索引。
我的计划是选择索引名称,然后将其放入alter语句中。
Select table_owner||'.'||INDEX_Name
from all_indexes
WHERE table_name = 'mytable'
and table_owner = 'myuser'
and uniqueness = 'UNIQUE';
ALTER INDEX (that select statement here)
RENAME TO abetterindexname
但是这引发了这个错误:
ORA-00953: missing or invalid index name
在发布之前我弄清楚了我的答案。这是有效的:
DECLARE
avariable varchar2(100);
BEGIN
Select table_owner||'.'||INDEX_Name
into avariable
from all_indexes
WHERE table_name = 'mytable'
and table_owner = 'myuser'
and uniqueness = 'UNIQUE';
execute immediate 'ALTER INDEX '||avariable||' RENAME TO abetterindexname';
END;
资料来源:https://asktom.oracle.com/pls/asktom/f?p=100:11:::::P11_QUESTION_ID:7038453003289。 - 我必须为execute immediate语句构建一个字符串。
如果有人知道如何只使用sql,我会感兴趣。
你不能在SQL中做到这一点。 SQL是一种查询语言。你只能使用DDL
ALTER INDEX <old name> RENAME TO <new name>
或者带有动态sql的plsql
begin
execute immediate 'ALTER INDEX '||<old name>||' RENAME TO '|| <new name>;
end;
可以使用新的12c WITH
函数在纯SQL语句中运行DDL。
下面的语句是一个普通的SELECT
语句,使用公用表表达式。但是这个公用表表达式引用了一个运行SQL语句的函数。此代码不需要安装任何对象,可以在SELECT
上下文中运行。
with function exec_sql(p_sql varchar2) return number is
pragma autonomous_transaction;
begin
execute immediate p_sql;
return 1;
end;
select exec_sql('ALTER INDEX '||owner||'.'||index_name||' RENAME TO abetterindexname')
from all_indexes
where table_name = 'MYTABLE'
and table_owner = owner
and uniqueness = 'UNIQUE';
/
但是不建议将这样的更改作为SELECT
语句的一部分来运行。 Oracle不保证执行SELECT
语句部分的确切顺序和次数(尽管在实践中我们通常可以解决它)。在PL / SQL匿名块中运行更改会更安全。这种技术可能仅适用于我们对数据库的访问权限有限的情况,例如仅运行SELECT
语句的工具。