Обновить оператор с помощью предложения - PullRequest
39 голосов
/ 21 марта 2011

У меня есть сценарий, который использует стек предложений 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, были бы весьма предпочтительнее, чем рефакторинг его для вложенных подзапросов.

Заранее спасибо,

Герт-Ян

Ответы [ 3 ]

44 голосов
/ 21 марта 2011

Если кто-нибудь придет за мной, это ответ, который сработал для меня.

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

27 голосов
/ 21 марта 2011

Синтаксис 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 гарантировать сохранение ключей.

Вы должны быть в состоянии использовать 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 голос
/ 17 июня 2019

Вы всегда можете сделать что-то вроде этого:

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

Теперь вы также можете использовать с оператором внутри обновления

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 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...