2015-10-30 30 views
4

我們有一個將LONG列轉換爲LOB的遷移腳本,如Oracle migration guide中所述,該表的索引現在需要重新構建。重建特定Oracle表的所有正常索引

假設表名是MY_TABLE,我一直在嘗試運行此腳本:

BEGIN 
    FOR index_entry IN (
     select INDEX_NAME from user_indexes where table_name='MY_TABLE' and index_type='NORMAL' 
    ) 
    LOOP 
     ALTER INDEX index_entry.index_name REBUILD; 
    END LOOP; 
END; 

但是,它失敗,出現以下語法錯誤:

PLS-00103: Encountered the symbol "ALTER" when expecting one of the following: 

    (begin case declare exit for goto if loop mod null pragma 
    raise return select update while with <an identifier> 
    <a double-quoted delimited-identifier> <a bind variable> << 
    continue close current delete fetch lock insert open rollback 
    savepoint set sql execute commit forall merge pipe purge 
[Failed SQL: BEGIN 
       FOR index_entry IN (
        select INDEX_NAME from user_indexes where table_name='MY_TABLE' and index_type='NORMAL' 
       ) 
       LOOP 
        ALTER INDEX index_entry.index_name REBUILD] 

即使這似乎以匹配此處指定的語法:Database PL/SQL Language Reference

ALTER不是一個有效的命令在循環中使用?

編輯:lad2025的建議下,嘗試使用EXECUTE IMMEDIATE像這樣:

5: LOOP 
6:  execute immediate 'alter index ' || index_entry.index_name || ' rebuild'; 
7: END LOOP; 

我收到:

ORA-06550: line 6, column 92: 
PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following: 

    * & = - + ; </> at in is mod remainder not rem return 
    returning <an exponent (**)> <> or != or ~= >= <= <> and or 
    like like2 like4 likec between into using || bulk member 
    submultiset 

    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:439) 

編輯2:EXECUTE IMMEDIATE工作正常。最終的文件問題涉及Liquibase執行我的劇本,我的遺忘與定義我<sql>塊:

<sql dbms="oracle" splitStatements="false"> 
            ^defaults to true 

重要的是,Liquibase默認分割語句的分號,這需要被關閉。

回答

7

您不能在PL/SQL塊中使用DDL語句。使用動態SQL:

BEGIN 
    ... 
    EXECUTE IMMEDIATE 'ALTER INDEX ' || index_entry.INDEX_NAME || ' REBUILD'; 
END 

編輯:

嘗試:

DECLARE 
BEGIN 
    FOR index_entry IN (select INDEX_NAME 
         from user_indexes 
         where table_name='MY_TABLE' and 
         index_type='NORMAL') 
    LOOP 
     dbms_output.put_line('ALTER INDEX ' || index_entry.INDEX_NAME || ' REBUILD'); 
     EXECUTE IMMEDIATE 'ALTER INDEX ' || index_entry.INDEX_NAME || ' REBUILD'; 
    END LOOP; 
END; 
/

SqlFiddleDemo

+0

問題更新 - 我給一個嘗試,卻收到了新的發現與「文件結束」相關的錯誤,但不是預期的。 –

+0

我會更新它 – lad2025

+0

謝謝 - 我已經嘗試了幾種不同的語法組合,但都沒有工作。 (儘管文檔中的每一個跡象表明他們_應該。) –