簡體   English   中英

如何在 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 ;

沒有過濾你剛剛重建的索引,它似乎不會獲得完全有用的信息。

那就是說......是否真的值得離線重建所有索引並使它們無法恢復? 可能不會,如果您不止一次這樣做並且從中受益,那么可能可以使用您的數據 model 更改某些內容以提供幫助。 仔細閱讀 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:以上是我的頭頂。 可能存在一些小的語法問題,但如果是這樣,您應該能夠解決它們。

Not 2:重建索引不是正常過程中需要做的事情。 Richard Foote 可能是 oracle 索引內部結構的最高權威,他是這樣說的: https://richardfoote.wordpress.com/2007/12/11/index-internals-rebuilding-the-truth/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM