2016-09-09 34 views
0

我試圖運行下面的存儲過程:運行PLSQL(甲骨文)的Liquibase錯誤的存儲過程:包裝或函數X處於無效狀態

CREATE OR REPLACE PROCEDURE RETRY_TRANS_EXCEPTION 
AS 
BEGIN 
FOR i IN 1..5 LOOP 
     DBMS_OUTPUT.PUT('Try #' || i); 
    ALTER TABLE CIS_CASE ADD TEST01 varchar2(1) NOT NULL; 
    END; 
END; 
/

,並要求其在changelog.xml爲:

<sql>CALL RETRY_TRANS_EXCEPTION();</sql>

我得到錯誤:

Liquibase update Failed: Migration failed for change set eldata-changelog.xml::2016-08-25-cn-01::Ch Will:Reason: liquibase.exception.DatabaseException: Error executing SQL CALL RETRY_TRANS_EXCEPTION(): ORA-06575: Package or function RETRY_TRANS_EXCEPTION is in an invalid state 

什麼,我想實現的是能夠運行存儲凝固酶原通過Liquibase通過一個循環來控制它。

感謝您的幫助Prashant。在什麼情況下,我的工作是你的解決方案,以及一個變化:

CREATE OR REPLACE PROCEDURE RETRY_TRANS_EXCEPTION 
AS 
v_query varchar2(100); 
BEGIN 
FOR i IN 1..500 LOOP 
     DBMS_OUTPUT.PUT('Try #' || i); 
     v_query := 'ALTER TABLE CIS_CASE ADD TEST01 varchar2(1) NULL'; 
    execute immediate v_query; 
    END loop; 
END; 
/

,然後從更新日誌調用存儲過程,如:

<changeSet id="2016-08-25-cw-01" author="Ch Will"> 
      <comment> 
         Testing retry logic on liquibase 
      </comment> 

    <sql>CALL RETRY_TRANS_EXCEPTION();</sql> 
</changeSet> 

回答

1
SQL> CREATE OR REPLACE PROCEDURE RETRY_TRANS_EXCEPTION 
    2 AS 
    3 BEGIN 
    4 FOR i IN 1..5 LOOP 
    5   DBMS_OUTPUT.PUT('Try #' || i); 
    6  ALTER TABLE CIS_CASE ADD TEST01 varchar2(1) NOT NULL; 
    7  END; 
    8 END; 
    9/
Warning: Procedure created with compilation errors 

SQL> show err 
Errors for PROCEDURE PRASHANT-MISHRA.RETRY_TRANS_EXCEPTION: 
LINE/COL ERROR 
-------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
6/4  PLS-00103: Encountered the symbol "ALTER" when expecting one of the following:  (begin case declare end 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 

沒有需要修正:

CREATE OR REPLACE PROCEDURE RETRY_TRANS_EXCEPTION 
AS 
v_query varchar2(100); 
BEGIN 
FOR i IN 1..5 LOOP 
     DBMS_OUTPUT.PUT('Try #' || i); 
     v_query := 'ALTER TABLE CIS_CASE ADD TEST01 varchar2(1) NOT NULL' ; 
    execute immediate v_query; 
    END loop; 
END; 
+0

不知道爲什麼我得到錯誤:原因:liquibase.exception.DatabaseException:執行SQL的錯誤CALL RETRY_TRANS_EXCEPTION():ORA-06576:不是有效的函數或過程名稱 – kamal

3

你不能把它的,因爲該過程不編譯正確。回去修復編譯錯誤,然後重試。

這裏有一些錯誤的脫穎而出對我說:

  1. for循環應該結束end loop;,不end;
  2. 你不能有DDL語句直接在代碼。你需要動態SQL從程序執行DDL語句:execute immediate 'ALTER TABLE CIS_CASE ADD TEST01 varchar2(1) NOT NULL';

附加說明:我不明白爲什麼你試圖在同一DDL語句多次執行循環中。顯然,你將無法一次又一次地添加同名的同一列。你會得到一個運行時錯誤。

+0

請原諒我的缺點與SQL和存儲過程。我試圖實現的目標是確保執行SQL語句的原因是數據量龐大,如果我能夠嘗試N次,它將保證最終執行(可能不是實現這一目標的最佳方法) – kamal

0

PLSQL存儲過程不能使用DDL語句,像

alter table ... 

所以

execute immediate ("...") 

語句是必需的,因爲在事實上它創造了一個自治無法回滾的隱式轉換