2012-02-17 55 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过程所做的更改)。

相关问题