2016-11-10 21 views
10

假設以下行mytable的:的Oracle SQL - 我可以返回 「之前」 一列值的狀態

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等價的方式來實現這個功能,所以我不必首先做一個「select」來獲得之前的值?

回答

8
update 
    (
    select T.*, (select letter from DUAL) old_letter 
    from myTable T 
    where id=1 
) 
    set letter = 'b' 
returning old_letter into myVariable; 

測試在甲骨文11.2

+3

這很有趣。 –

+0

Brillant解決方案!它可以簡化一點,只是'選擇T. *,T.letter AS old_letter .....' – krokodilko

+2

@krokodilko我測試過「簡體」字母爲old_letter' - 不工作。 Oracle在這種情況下返回新的價值。只有子選擇欺騙Oracle – Mike

1

我相信你無法用一個簡單的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

+0

非常感謝@Aleksej - 按我的意見邁克我會選擇select,然後通過這種方法進行更新。然而,我想你的答案突出了我發現的奇怪之處:Oracle觸發器可以訪問:old和new值,但是從我在這裏看到的答案來看,Oracle並不通過SQL公開相同的功能。有很多用例,我甚至無法將它們全部列出。 – Pancho

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

非常感謝@Kacper - 我想我寧願使用select,然後通過這種方法更新 – Pancho

+0

@Pancho是的我也認爲select更好。 – Kacper

相關問題