2016-03-15 7 views
0

У меня есть несколько SQL-файлы, которые выполняются один за другим в сценарии, как это:Oracle. Как реализовать вложенные транзакции

@script-A.sql; 
@script-B.sql; 
@script-C.sql; 
... 

каждый файл сценария делает что-то Usefull и выглядит следующим образом:

DECLARE 
... 
BEGIN 

    EXECUTE IMMEDIATE 'TRUNCATE SOME-TABLE'; 
    -- lots of inserts into SOME_TABLE 
    COMMIT; 
END; 
/

Я должен обернуть выполнение файлов sql в одной большой транзакции. Если выполнение любого файла sql не выполняется, все предыдущие изменения файла sql должны быть отменены.

Как это сделать?

p.s

, как @Mat заметили изменения DDL (усечение таблицы) не может быть rollbacked. Я могу реорганизовать эту строку кода, если это необходимо.

+3

Вы не можете откатить DDL (усечения является DDL), так что ... – Mat

+0

@Mat всё изменится, если я реорганизовать «усечение» в «исключить из»? – user149691

+0

Да, удалить DML, и вы можете откатиться от него. – sagi

ответ

0

Сначала вы должны устранить DDL и зафиксировать свой код. Затем добавьте одну строку commit после выполнения скрипта. И, наконец, все, что вам нужно, - это установить параметр SQL * Plus для отката транзакции по ошибке firts. Таким образом, вы должны установить WHENEVER SQLERROR EXIT ROLLBACKhttp://docs.oracle.com/cd/B19306_01/server.102/b14357/ch12052.htm

Вы можете увидеть некоторые примеры использования здесь Oracle 11 - sqlplus - rollback the whole script on error - how?

1

Вот лучший способ, который вы можете использовать для управления сделки по сохраняя обработку внутри каждого сценария, так что исключение если какая-либо транзакция не удалась, все изменения будут отменены. Единственное условие здесь состоит в том, чтобы сохранить COMMIT в самом конце, чтобы на успешной транзакции последнего wil fire COMMIT. Надежда ниже фрагмента помогает.

------------------------------Script 1----------------------------------------- 


--Simple query to delete from records 
DECLARE 
    p_err_cd PLS_INTEGER; 
    p_err_msg VARCHAR2(100 CHAR); 
BEGIN 
-- EXECUTE IMMEDIATE 'DELETE EMP '; 
    INSERT INTO EMP 
    SELECT '123', 'AVRJIT', 'DB', 12, SYSDATE, 1200, 123, 10, '123' FROM DUAL; 
EXCEPTION 
WHEN OTHERS THEN 
ROLLBACK; 
    p_err_cd := SQLCODE; 
    p_err_msg:=SQLERRM; 
dbms_output.put_line('Transaction Rollback'); 
END; 
/

---------------------------------Script 2 ---------------------------------- 
--Simple query to delete from records 
DECLARE 
    p_err_cd PLS_INTEGER; 
    p_err_msg VARCHAR2(100 CHAR); 
BEGIN 
-- EXECUTE IMMEDIATE 'DELETE EMP '; 
    INSERT INTO EMP 
    SELECT '123A', 'AVRJIT', 'DB', 12, SYSDATE, 1200, 123, 10, '123' FROM DUAL; 
EXCEPTION 
WHEN OTHERS THEN 
ROLLBACK; 
    p_err_cd := SQLCODE; 
    p_err_msg:=SQLERRM; 
dbms_output.put_line('Transaction Rollback'); 
END; 
/
----------------------------------------------------------------------------- 
Since EMP table has EMPNO as NUMBER field so the second script will fail. 
While running the main executing file i.e Full_script.sql 


set serveroutput on; 
@C:\Av_test_script\Stack_overflow\full_script.sql 


PL/SQL procedure successfully completed. 

PL/SQL procedure successfully completed. --> Failed as EMPNO column here is of Invalid datatype 

Transaction Rollback 
Смежные вопросы