2016-11-10 89 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

相关问题