Ответ 1
update
(
select T.*, (select letter from DUAL) old_letter
from myTable T
where id=1
)
set letter = 'b'
returning old_letter into myVariable;
Протестировано на Oracle 11.2
Предположим следующую строку в myTable:
id = 1
letter = 'a'
В Oracle можно легко сделать следующее:
update myTable set
letter = 'b'
where id = 1
returning letter
into myVariable;
и myVariable будет удерживать значение 'b'.
То, что я ищу, - это способ возврата знака "до"
т. замените предыдущее обновление на:
update myTable set
letter = 'b'
where id = 1
returning letter "before the update"
into myVariable;
, а myVariable должен удерживать значение 'a';
Я понимаю, что T-SQL может достичь этого с помощью предложения OUTPUT.
Есть ли эквивалентный способ Oracle для достижения этого, поэтому мне не нужно сначала делать "выбор", чтобы получить значение до?
update
(
select T.*, (select letter from DUAL) old_letter
from myTable T
where id=1
)
set letter = 'b'
returning old_letter into myVariable;
Протестировано на Oracle 11.2
Я считаю, что вы не можете сделать это с помощью простого оператора SQL (и я ошибаюсь, учитывая ответ Майкса:-))
Один из способов - использовать другой столбец и триггер; например, скажем, что у вас есть таблица со столбцом a
, вы можете добавить еще один столбец old_a
для хранения старого значения a
и заполнить его триггером:
create table testUpdate(a number, old_a number);
create or replace trigger trgUpdate
before update on testUpdate
for each row
begin
if :new.a != :old.a then /* assuming not null values for simplicity */
:new.old_a := :old.a;
end if;
end;
insert into testUpdate values (1, null);
При запуске обновления старое значение сохраняется в столбце th old_a
и возвращается в returning
предложение
SQL> declare
2 vA number;
3 begin
4 update testUpdate
5 set a = 9
6 returning old_a
7 into vA;
8 --
9 dbms_output.put_line(vA);
10 end;
11 /
1
Однако, учитывая, что для добавления таблицы необходимо добавить столбец и триггер, я считаю это решение более упражнением, чем то, что я хотел бы иметь в производственной БД
Если обновлений не много, вы можете выполнить обновление в цикле и получить старые значения:
declare
CURSOR c IS SELECT letter, id FROM myTable
FOR UPDATE OF letter;
begin
open c;
for x in c loop
-- old value is in x.letter. You can assign it here
update myTable set letter = 'b' where id = x.id;
end loop;
commit;
close c;
end;
/