Как в PL SQL выполнить update и delete в рамках одной транзакции?

Вот фрагмент pl sql кода, где в блоке есть две DML команды - update и delete:

if p_status = 'f_rep' or p_status = 't_rep' then
    select doc_id into docId from DOCS where id = p_Id;
    update DOC_ACTIVE set is_active = 0 where pay_id = doc_id;
    select cred_id into credId from (
        select cred_id from DBO_PART where doc_id = 457229
        union all
        select cred_id from DBO_FULL where doc_id = 457229);
    delete from DBO_SAFE where credit_id = credId;
    commit;
    dbms_output.put_line(docId);
end if;

Мне нужно, чтобы они выполнились либо обе, либо ни одна. Прочитал, что в оракле нет такого понятия как begin transaction. Поэтому вопрос - правильно ли я написал пример, чтобы добиться указанного эффекта?


Ответы (1 шт):

Автор решения: 0xdb

выполнились либо обе, либо ни одна ... правильно ли я написал пример

Правильно, но не потому, что:

Прочитал, что в оракле нет такого понятия как begin transaction

Это понятие есть: транзакция начинётся неявно любым DML запросом запросившим TX lock, или явно с выполнением SET TRANSACTION.

В PL/SQL блоке без EXCEPTION выполнятся либо все DML запросы, либо ни один из них, то есть блок завершится исключением и неявным откатом всех изменений:

create table t1 (id, val) as
    select 1, 0 from dual 
/
create table t2 (id primary key, val) as
    select 1, 9 from dual 
/
alter table t1 modify id references t2 
/

begin
    update t1 set
        val = (select val from t2 where t2.id=t1.id);
    dbms_output.put_line (sql%rowcount||' row(s) updated.'); 
    delete from t2; 
end;
/
1 row(s) updated.

Error report -
ORA-02292: integrity constraint (DB.SYS_C0014996) violated - child record found

select * from t1;

         ID         VAL
----------- -----------
          1           0
→ Ссылка