我有一个脚本,它使用一堆 with 子句来得出一些结果,然后我想将该结果写入表中。我只是无法理解它,有人可以指出我正确的方向吗?
这是一个简化的示例,表明我想要做什么:
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 子句,它们都互相引用,因此任何实际使用 with 子句的建议都比将其重构为嵌套子查询更受青睐。
如果有人追随我来到这里,这就是对我有用的答案。
注意:请在使用前阅读评论,这并不完整。 我可以给出的更新查询的最佳建议是切换到 SqlServer ;)
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
WITH 语法在内联视图中似乎有效,例如
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 保证密钥保存的能力。
不过,您应该能够使用合并。 使用您发布的简单示例,这甚至不需要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
子句。
你总是可以做这样的事情:
update mytable t
set SomeColumn = c.ComputedValue
from (select *, 42 as ComputedValue from mytable where id = 1) c
where t.id = c.id
您现在还可以在 update 中使用 with 语句
update mytable t
set SomeColumn = c.ComputedValue
from (with abc as (select *, 43 as ComputedValue_new from mytable where id = 1
select *, 42 as ComputedValue, abc.ComputedValue_new from mytable n1
inner join abc on n1.id=abc.id) c
where t.id = c.id
大多数时候,我更喜欢“With”声明,但我不知道如何应用它,如果可能的话。因此,我决定将相同的知识应用于我“创建”的表(我相信它指的是内联视图)。尝试以下方法:
当我尝试更新多个项目的多个值并使用 case 语句将字段的特定值从一个表应用到另一个表时,这对我来说非常有用。
update ( select i.item_id,
i.item_name,
i.nmfc_code,
i.dim_uom_id,
w.f_class
from item i
left join
warehouse w on
i.item_id = w.item_id
)
set dim_uom_id = 4,
nmfc_code = case f_class
when '50' then 1
when '92.5' then 2
when '125' then 3
when '150' then 4
end
where
item_id in ( select item_id
from item
where item_name in (
'i1',
'i2',
'i3',
'i4',
'i5'
)
)