2012-05-08 41 views
0

我爲工作中的應用程序創建了一個flyway項目。事實證明,其中一位開發人員已經在TEST上執行了一些SQL語句,然後我已經準備好進行測試。flyway:即使SQL語句失敗也會強制遷移

我的SQL腳本有幾個語句:

ALTER TABLE "TABLE1" MODIFY ("NAME" VARCHAR2(75 CHAR)); 
ALTER TABLE "TABLE2" DROP ("BOARD_ID"); 
ALTER TABLE "TABLE3" ADD CONSTRAINT "SYS_C0022270" CHECK ("ID" IS NOT NULL) ENABLE; 

,應該在聲明#2被丟棄列,已經下降了手動對我們的測試實例。它還沒有被放在我們的PROD實例上,我想通過遷移而不是手動完成。

很明顯,我沒有在PROD上進行遷移,沒有在TEST上首先嚐試它(這裏有比這三個查詢更多的東西)。

但是由於遷移我遇到問題是第一個問題,所以無法繼續。

有什麼辦法強制它通過?我知道該列已被刪除。我可以再次創建它,然後讓遷移將其刪除。但是我可能會有其他查詢可能失敗(創建可能已存在的種子數據等)。我不希望那樣停止我們的部署。

除了從PROD再次克隆我們的數據庫並讓開發團隊停止開發,同時準備一組新的遷移之外,還有什麼想法?

回答

1

通過它的聲音,再造列確確實實聽起來像的最佳解決方案。

這是超級簡單的,如果唯一的目的是讓列後立即再次下降,絕對無害。

除非我錯過了故事的一部分,否則我無法理解未來種子數據的創建過程會如何與此衝突。

長期的解決方案當然是dev文化的變化,完全禁止手工更改數據庫。

+0

給你一個種子數據衝突的例子:我們有一些指向存儲在數據庫中的碧玉模板的對象。多於一條記錄指向該模板。每個對象的SQL腳本都有一個查詢來創建模板,以防它不存在。 (因爲在開發時不知道哪個對象會首先被部署)。在第一個腳本運行後,所有其他腳本都會失敗,因爲我們並不關心其中的一個查詢,因爲它已經被插入。 – robertrv

+0

我知道我們應該從每個文件中刪除查詢,並將其作爲一個獨立的腳本。但是忽略失敗查詢的方法也可以起作用。現在,我並不建議您實施這樣的功能,因爲我們有獨特的需求。我只是想知道是否有類似的地方。 – robertrv

+0

這和丟失的列有什麼關係?或者這只是衆多的一個例子? –

0

如果你用sqlplus運行腳本,那麼你可以在開頭添加以下語句:

WHENEVER SQLERROR CONTINUE 
+0

這不起作用:'ORA-00900:無效的SQL語句'。我猜這是一個SQL * Plus只有構造。 – robertrv

4

你可以把你想忽略與一個PL/SQL塊中的錯誤的任何SQL語句異常處理程序:

BEGIN 
    EXECUTE IMMEDIATE 'ALTER TABLE "TABLE1" MODIFY ("NAME" VARCHAR2(75 CHAR))'; 
EXCEPTION 
    WHEN OTHERS THEN 
    -- perhaps print a message about the command failure here 
END; 
/

DDL必須在PL/SQL中的execute immediate語句內完成。

有點痛苦,但它應該工作。

+0

謝謝!這確實有用。唯一的問題是,flyway似乎不會返回任何「DBMS_OUTPUT.PUT_LINE()」返回的內容。我將使用sqlplus編寫一些簡單的腳本,在我們即將發佈的版本之後,重新克隆我們的PROD數據庫並重新開始。 – robertrv

+0

您也可以使用utl_file將消息寫入文件。 – DCookie

0

WHENEVER SQLERROR CONTINUE和 DBMS_OUTPUT.PUT_LINE()的遷徙路線一點兒也不工作是SQLPLUS客戶特定的,你可以使用RAISE

EXCEPTION 

WHEN OTHERS THEN 

DBMS_OUTPUT.PUT_LINE(SQLERRM || CHR(10) ||DBMS_UTILITY.FORMAT_ERROR_BACKTRACE); 

ROLLBACK; 

Raise_Application_Error (-20000, SQLERRM || ' : ' ||DBMS_UTILITY.FORMAT_ERROR_BACKTRACE); 

END; 

遷徙路線將停止遷移過程和日誌打印問題。

如果您想繼續遷移,請不要用戶引用另一個打印解決方案。 使用flyway 4.0進行測試。3