2011-03-21 46 views
35

我有一个脚本,使用与子句的堆栈来产生一些结果,然后我想将结果写入表中。我无法绕过它,有人能指引我走向正确的方向吗?更新语句使用与条款

这里有一个简单的例子,表示什么,我想做的事:

with comp as (
    select *, 42 as ComputedValue from mytable where id = 1 
) 
update t 
set  SomeColumn = c.ComputedValue 
from mytable t 
     inner join comp c on t.id = c.id 

真实的东西,有相当与实际使用with子句将高度优先的条款,所有的相互引用,所以任何建议几个通过重构它嵌套子查询。

由于提前,

格特-JAN

+2

FYI:您不必编辑您的标题和问题指出,你自己回答了这个问题。只需添加您的解决方案作为自己的答案,并选择它,如果它是最好的。 – 2011-03-21 17:25:26

+0

好的,不能将它标记为已回答。谢谢! – gjvdkamp 2011-03-21 18:15:55

+0

我正在寻找一个响应也,我发现它在这里:http://stackoverflow.com/questions/7030699/oracle-sql-update-with-data-from-another-table – Bogdan 2013-07-30 06:38:47

回答

36

如果有人来到我身后,这是对我有用的答案。

update mytable t 
set z = (
    with comp as (
    select b.*, 42 as computed 
    from mytable t 
    where bs_id = 1 
) 
    select c.computed 
    from comp c 
    where c.id = t.id 
) 

祝你好运,

GJ

+3

这不会更新所有行吗?如果有行的c.id <> t.id,它们不会被设置为null吗?有没有人知道一种方法把外部的where子句放在外面? – 2013-04-22 05:29:04

+0

不要再使用Oracle了,这是一段时间了。试试吧,让我们知道;-) IIRC这为我工作。 – gjvdkamp 2013-04-22 07:47:41

+0

@gjvdkamp就像Sanjay Nambiar说的那样工作:更新对所选行有效,但其他所有不在“where”的行都设置为null。 [2]有没有人知道一种方法来把外部的where子句呢? – robsonrosa 2015-09-01 20:40:29

24

的语法似乎是有效的在共线视图,例如

UPDATE (WITH comp AS ... 
     SELECT SomeColumn, ComputedValue FROM t INNER JOIN comp ...) 
    SET SomeColumn=ComputedValue; 

但在快速测试我这样做总是失败ORA-01732: data manipulation operation not legal on this view,虽然它成功,如果我重写,以消除WITH子句。因此,重构可能会干扰Oracle保证密钥保护的能力。

不过你应该可以使用MERGE。使用你已经张贴了这个简单的例子甚至不需要WITH子句:

MERGE INTO mytable t 
USING (select *, 42 as ComputedValue from mytable where id = 1) comp 
ON (t.id = comp.id) 
WHEN MATCHED THEN UPDATE SET SomeColumn=ComputedValue; 

但据我所知,你必须要分解出更复杂的子查询。我认为您可以使USING条款中的子查询任意复杂,并包含多个WITH子句。

+1

嗨,非常感谢你的努力,已经设法让它运行。我使用的with语句具有计算平均值和stddevs的相当多的级别,然后使用其他表格中的规范化(统计)数据不会造成重构的真正痛苦。该示例只是更新语法。 – gjvdkamp 2011-03-21 17:17:43