2012-02-17 52 views
0

我有一個PL/SQL腳本,它運行一堆命令,並在最後調用commit。有沒有辦法在oracle中進行選擇性提交?

select count(*) into countCol from USER_TAB_COLUMNS where TABLE_NAME = 'EVAPP_CARLETON_RESULT' and COLUMN_NAME = 'AMTFIN' and DATA_SCALE is null; 
IF (countCol <> 0) then 

execute immediate 'alter table EVAPP_CARLETON_RESULT add AMTFIN_TMP NUMBER(10,2)' ; 

execute immediate 'update EVAPP_CARLETON_RESULT set AMTFIN_TMP = AMTFIN' ; 

execute immediate 'alter table EVAPP_CARLETON_RESULT drop column AMTFIN' ; 

execute immediate 'alter table EVAPP_CARLETON_RESULT rename column AMTFIN_TMP to AMTFIN' ; 


DBMS_OUTPUT.put_line('This column EVAPP_CARLETON_RESULT.AMTFIN has been modified to the required precision'); 
END IF; 
logger('68'); 

evaluate.commitScript; 

在此之前有68個這樣的塊,但evaluate.commitScript在最後被調用。

但是,記錄器在每個這樣的塊之後被調用,並且它內部有一個提交語句。

create or replace 
PROCEDURE LOGGER 
(MESSAGE1 IN VARCHAR2 ) AS 
pragma autonomous_transaction; 
    BEGIN 
    insert into message_log (datetime, message) values (sysdate, message1); 
    commit; 
    END LOGGER; 

該提交同時提交所有更改。不僅僅是程序所做的更改。無論如何,我們可以選擇性地調用提交嗎?

回答

7

看起來你已經有這條線在Logger PROC解決方案:

pragma autonomous_transaction 

該聲明將在過程中一個單獨的事務。在那裏簽發的COMMIT將不會在該程序之外進行任何交易。

另外,EXECUTE IMMEDIATE語句中的DDL是隱式提交的。

4

LOGGER程序中的commit只會提交該調用LOGGER過程所做的更改。

如果您發佈的代碼段代表68個塊,則問題在於DDL語句(如ALTER TABLE)隱式發出兩個提交 - 一個在執行語句之前執行,一個在執行成功後執行一個。這意味着DDL不能以事務方式完成,並且evaluate.commitScript調用既不提交也不回滾任何更改。

根據Oracle版本,版本和配置的不同,您可能能夠在運行腳本之前使用類似Oracle flashback database的東西創建恢復點,並在腳本失敗時閃回到該恢復點(儘管這也會回滾您的LOGGER過程所做的更改)。

相關問題