Есть ли способ сделать выборочный коммит в оракуле? - PullRequest
0 голосов
/ 17 февраля 2012

У меня есть сценарий 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 таких блоков, но в самом конце вызывается метод define.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;

Коммит фиксирует все изменения одновременно. Не только изменения, сделанные процедурой. Есть ли вообще, мы можем вызывать коммит выборочно?

Ответы [ 2 ]

7 голосов
/ 17 февраля 2012

Похоже, у вас уже есть решение с этой строкой в ​​процедуре LOGGER:

pragma autonomous_transaction

Этот оператор устанавливает отдельную транзакцию в процедуре.Выданный там COMMIT не будет совершать никаких транзакций вне этой процедуры.

Кроме того, DDL в операторах EXECUTE IMMEDIATE неявно фиксируется.

4 голосов
/ 17 февраля 2012

commit в процедуре LOGGER будет фиксировать только изменения, сделанные этим вызовом процедуры LOGGER.

Если опубликованный вами фрагмент представляет 68 блоков, проблема заключается в том, что операторы DDL (например, ALTER TABLE) неявно выдают два коммита - один до выполнения оператора и один после выполнения, если выполнение было успешным. Это означает, что DDL не может быть выполнен транзакционно, и вызов evaluate.commitScript не фиксирует и не откатывает никаких изменений.

В зависимости от версии, выпуска и конфигурации Oracle вы можете использовать что-то вроде База данных флэш-памяти Oracle для создания точки восстановления перед запуском сценария и возврата к этой точке восстановления, если ваш Сбой сценария (хотя это также откатит изменения, сделанные вашей LOGGER процедурой).

...