source

Oracle SQL - 열 값의 "이전" 상태를 반환할 수 있습니까?

factcode 2023. 10. 31. 22:56
반응형

Oracle SQL - 열 값의 "이전" 상태를 반환할 수 있습니까?

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' 값을 유지해야 합니다.

저는 OUTPUT 조항을 통해 T-SQL이 이를 달성할 수 있다고 알고 있습니다.

이전 값을 얻기 위해 먼저 "선택"할 필요가 없도록 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에서 테스트 완료

업데이트가 많지 않은 경우 루프에서 업데이트를 수행하여 이전 값을 가져올 수 있습니다.

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;
/

간단한 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);

업데이트를 실행하면 이전 값이 다음에 저장됩니다.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

하지만, 당신의 테이블에 열과 트리거를 추가해야 한다는 점을 감안할 때, 저는 이 솔루션이 프로덕션 DB에서 제가 원하는 것 이상의 연습이라고 생각합니다.

언급URL : https://stackoverflow.com/questions/40522950/oracle-sql-can-i-return-the-before-state-of-a-column-value

반응형