Как правильно архивировать данные без «потерянного обновления»?
Вот что я хочу сделать:
INSERT INTO
SELECT FOR UPDATE
DELETE SELETED rows.
Но синтаксис FOR UPDATE
не поддерживается в INSERT INTO ... SELECT...
Можно ли решить проблему, используя только SQL без курсора на PL / SQL?
Пример
create table authority(id number, key varchar2(128));
create table authority_arch(id number, key varchar2(128));
insert into authority(1, 'random_key1');
insert into authority(1, 'random_key2');
insert into authority(1, 'random_key3');
insert into authority(2, 'random_key4');
insert into authority(2, 'random_key5');
commit;
1 сессия
insert into authority_arch
select * from authority where id=2;
-- in this moment 2 session make insert! 'Lose rows' in next delete
delete from authority where id=2;
2 сеанса
insert into authority(2, 'random_key6', sysdate+1);
commit;
в результате есть:
select * from authority
id | key
-----------
1 | random_key1
1 | random_key2
1 | random_key3
но я хочу удалить ТОЛЬКО выбранные строки
id | key
-----------
1 | random_key1
1 | random_key2
1 | random_key3
2 | random_key6
В качестве решения я использую:
for rec in (select rowid as rid, a.* from authority a where id=2 FOR UPDATE nowait) loop
insert into authority_arch values(rec.id, rec.key);
delete from authority where rowid=rec.rid;
end loop;