Как в 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 шт):
выполнились либо обе, либо ни одна ... правильно ли я написал пример
Правильно, но не потому, что:
Прочитал, что в оракле нет такого понятия как 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