如何在 Oracle 循环中的 select 语句中执行 alter 命令?
How to execute alter command within select statement in a loop in Oracle?
我正在尝试通过脚本重建模式的索引,但我卡在了通过 select 语句获取字符串 ALTER INDEX OWNER.INDEX_NAME REBUILD NOLOGGING 的位置,但我没有得到如何执行alter命令,请指导:
我试图为 str 分配第二个 for 循环中使用的 select 查询的值,然后执行它但出现错误。
IS
STR VARCHAR2(5000);
BEGIN
FOR T IN (
SELECT USERNAME FROM DBA_USERS WHERE USERNAME ='REPORT'
)
LOOP
FOR CUR IN
(
SELECT ' ALTER INDEX '||OWNER||'.'||INDEX_NAME|| ' REBUILD NOLOGGING; ' FROM DBA_INDEXES
WHERE OWNER=T.USERNAME AND TEMPORARY='N'
)
LOOP
--- EXECUTE IMMEDIATE STR ;
INSERT INTO INDEX_REBUILD_HISTORY
SELECT DISTINCT OWNER, TRUNC(LAST_DDL_TIME) from DBA_OBJECTS where OBJECT_TYPE = 'INDEX'
AND
OWNER=T.USERNAME ;
COMMIT;
END LOOP;
END LOOP;
END ;
“它出错了。”没有您收到的实际错误没有帮助。那就是说你犯了很多其他人犯的同样的错误,你不应该包括“;”作为动态的一部分 SQL - 它不是语句的一部分,它仅供您的客户用来了解何时将代码发送到数据库。
FOR CUR IN
(
SELECT ' ALTER INDEX '||OWNER||'.'||INDEX_NAME|| ' REBUILD NOLOGGING' ddl_cmd FROM DBA_INDEXES
WHERE OWNER=T.USERNAME AND TEMPORARY='N'
)
...
EXECUTE IMMEDIATE CUR.ddl_cmd ;
(我还为该列指定了别名,以便您可以在循环中很好地使用它。
然后
INSERT INTO INDEX_REBUILD_HISTORY
SELECT DISTINCT OWNER, TRUNC(LAST_DDL_TIME) from DBA_OBJECTS where OBJECT_TYPE = 'INDEX'
AND
OWNER=T.USERNAME ;
没有过滤您刚刚重建的索引,它似乎不会获得完全有用的信息。
也就是说……
离线重建所有索引并使它们不可恢复真的值得吗?可能不会,如果您不止一次这样做并且从中受益,那么您的数据模型可能会有所改变以提供帮助。仔细阅读 Richard Foote 的演讲,他是一位知名的 Oracle 索引专家 https://richardfoote.files.wordpress.com/2007/12/index-internals-rebuilding-the-truth.pdf 我怀疑您是否会认为重建所有索引是一个解决方案而放弃它。
您使用动态sql。而且您不需要外循环。 dba_indexes:
中可用的过滤器
create procedure bld_idx
is
vsql varchar2(500);
for x in (select owner,
index_name
from dba_indexes
where owner = 'REPORT'
and TEMPORARY='N'
)
loop
vsql := ' ALTER INDEX '||x.OWNER||'.'||x.INDEX_NAME|| ' REBUILD NOLOGGING; ';
dbms_output.put_line(vsql); -- debugging only
execute immediate vsql;
end loop;
end;
注1:以上是我的头脑。可能存在一些小的语法问题,但如果是这样,您应该能够解决它们。
不是2:重建索引不是正常过程中需要做的事情。 Richard Foote 可能是 Oracle 索引内部结构的最高权威,他是这样说的:https://richardfoote.wordpress.com/2007/12/11/index-internals-rebuilding-the-truth/
我正在尝试通过脚本重建模式的索引,但我卡在了通过 select 语句获取字符串 ALTER INDEX OWNER.INDEX_NAME REBUILD NOLOGGING 的位置,但我没有得到如何执行alter命令,请指导:
我试图为 str 分配第二个 for 循环中使用的 select 查询的值,然后执行它但出现错误。
IS
STR VARCHAR2(5000);
BEGIN
FOR T IN (
SELECT USERNAME FROM DBA_USERS WHERE USERNAME ='REPORT'
)
LOOP
FOR CUR IN
(
SELECT ' ALTER INDEX '||OWNER||'.'||INDEX_NAME|| ' REBUILD NOLOGGING; ' FROM DBA_INDEXES
WHERE OWNER=T.USERNAME AND TEMPORARY='N'
)
LOOP
--- EXECUTE IMMEDIATE STR ;
INSERT INTO INDEX_REBUILD_HISTORY
SELECT DISTINCT OWNER, TRUNC(LAST_DDL_TIME) from DBA_OBJECTS where OBJECT_TYPE = 'INDEX'
AND
OWNER=T.USERNAME ;
COMMIT;
END LOOP;
END LOOP;
END ;
“它出错了。”没有您收到的实际错误没有帮助。那就是说你犯了很多其他人犯的同样的错误,你不应该包括“;”作为动态的一部分 SQL - 它不是语句的一部分,它仅供您的客户用来了解何时将代码发送到数据库。
FOR CUR IN
(
SELECT ' ALTER INDEX '||OWNER||'.'||INDEX_NAME|| ' REBUILD NOLOGGING' ddl_cmd FROM DBA_INDEXES
WHERE OWNER=T.USERNAME AND TEMPORARY='N'
)
...
EXECUTE IMMEDIATE CUR.ddl_cmd ;
(我还为该列指定了别名,以便您可以在循环中很好地使用它。
然后
INSERT INTO INDEX_REBUILD_HISTORY
SELECT DISTINCT OWNER, TRUNC(LAST_DDL_TIME) from DBA_OBJECTS where OBJECT_TYPE = 'INDEX'
AND
OWNER=T.USERNAME ;
没有过滤您刚刚重建的索引,它似乎不会获得完全有用的信息。
也就是说…… 离线重建所有索引并使它们不可恢复真的值得吗?可能不会,如果您不止一次这样做并且从中受益,那么您的数据模型可能会有所改变以提供帮助。仔细阅读 Richard Foote 的演讲,他是一位知名的 Oracle 索引专家 https://richardfoote.files.wordpress.com/2007/12/index-internals-rebuilding-the-truth.pdf 我怀疑您是否会认为重建所有索引是一个解决方案而放弃它。
您使用动态sql。而且您不需要外循环。 dba_indexes:
中可用的过滤器create procedure bld_idx
is
vsql varchar2(500);
for x in (select owner,
index_name
from dba_indexes
where owner = 'REPORT'
and TEMPORARY='N'
)
loop
vsql := ' ALTER INDEX '||x.OWNER||'.'||x.INDEX_NAME|| ' REBUILD NOLOGGING; ';
dbms_output.put_line(vsql); -- debugging only
execute immediate vsql;
end loop;
end;
注1:以上是我的头脑。可能存在一些小的语法问题,但如果是这样,您应该能够解决它们。
不是2:重建索引不是正常过程中需要做的事情。 Richard Foote 可能是 Oracle 索引内部结构的最高权威,他是这样说的:https://richardfoote.wordpress.com/2007/12/11/index-internals-rebuilding-the-truth/