【问题标题】:Is there a way to combine a SELECT and ALTER statement (combining DML and DDL)?有没有办法结合 SELECT 和 ALTER 语句(结合 DML 和 DDL)?
【发布时间】:2019-04-17 19:00:01
【问题描述】:

我想动态重命名索引。

背景故事:如果基表有主键(我认为?),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。 -- 我必须为立即执行语句构建一个字符串。

如果有人知道如何仅使用 sql 执行此操作,我会很感兴趣。

【问题讨论】:

  • 您应该edit 问题并将回答路径移动到您接受的答案。

标签: sql oracle plsql ddl


【解决方案1】:

你不能在 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;

【讨论】:

    【解决方案2】:

    可以使用新的 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 语句的工具。

    【讨论】:

      猜你喜欢
      • 2015-12-15
      • 2016-04-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-20
      • 2019-11-09
      • 2011-02-23
      • 2012-03-05
      相关资源
      最近更新 更多