有没有办法在oracle中进行选择性提交?

时间:2012-02-17 15:44:27

标签: oracle stored-procedures plsql

我有一个PL / SQL脚本,它运行一堆命令,并在最后调用commit。

 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。

但是,logger在每个这样的块之后被调用,并且它内部有一个commit语句。

 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;

提交同时提交所有更改。不仅仅是程序所做的更改。无论如何,我们可以选择性地调用commit吗?

2 个答案:

答案 0 :(得分:7)

看起来你已经在LOGGER proc中使用了这一行的解决方案:

pragma autonomous_transaction

该语句在过程中设置单独的事务。在那里发布的COMMIT不会在该过程之外提交任何事务。

此外,EXECUTE IMMEDIATE语句中的DDL是隐式提交的。

答案 1 :(得分:4)

commit过程中的LOGGER只会提交LOGGER程序调用所做的更改。

如果您发布的代码段代表68个块,则问题是DDL语句(如ALTER TABLE)隐式发出两个提交 - 一个在执行语句之前,一个在执行之后执行时成功的。这意味着DDL无法以事务方式完成,evaluate.commitScript调用既不会提交也不会回滚任何更改。

根据Oracle版本,版本和配置的不同,您可以使用Oracle flashback database之类的内容在运行脚本之前创建还原点,并在脚本失败时闪回到该还原点(尽管这也会回滚您LOGGER程序所做的更改。