Обновление оператора с внутренним соединением в Oracle - PullRequest
260 голосов
/ 15 марта 2010

У меня есть запрос, который отлично работает в MySQL, но когда я запускаю его в Oracle, я получаю следующую ошибку:

Ошибка SQL: ORA-00933: команда SQL неправильно завершена
00933. 00000 - «Команда SQL неправильно завершена»

Запрос:

UPDATE table1
INNER JOIN table2 ON table1.value = table2.DESC
SET table1.value = table2.CODE
WHERE table1.UPDATETYPE='blah';

Ответы [ 14 ]

367 голосов
/ 15 марта 2010

Этот синтаксис недопустим в Oracle. Вы можете сделать это:

UPDATE table1 SET table1.value = (SELECT table2.CODE
                                  FROM table2 
                                  WHERE table1.value = table2.DESC)
WHERE table1.UPDATETYPE='blah'
AND EXISTS (SELECT table2.CODE
            FROM table2 
            WHERE table1.value = table2.DESC);

Или вы могли бы сделать это:

UPDATE 
(SELECT table1.value as OLD, table2.CODE as NEW
 FROM table1
 INNER JOIN table2
 ON table1.value = table2.DESC
 WHERE table1.UPDATETYPE='blah'
) t
SET t.OLD = t.NEW

(Это зависит от того, считается ли встроенное представление обновляемым в Oracle).

186 голосов
/ 15 марта 2010

Используйте это:

MERGE
INTO    table1 trg
USING   (
        SELECT  t1.rowid AS rid, t2.code
        FROM    table1 t1
        JOIN    table2 t2
        ON      table1.value = table2.DESC
        WHERE   table1.UPDATETYPE='blah'
        ) src
ON      (trg.rowid = src.rid)
WHEN MATCHED THEN UPDATE
    SET trg.value = code;
19 голосов
/ 07 мая 2015

Слияние с тем, где у меня работал пункт:

merge into table1
using table2
on (table1.id = table2.id)
when matched then update set table1.startdate = table2.start_date
where table1.startdate > table2.start_date;

Вам нужно предложение WHERE, поскольку столбцы, на которые есть ссылки в предложении ON, не могут быть обновлены.

13 голосов
/ 15 марта 2010
 UPDATE ( SELECT t1.value, t2.CODE
          FROM table1 t1
          INNER JOIN table2 t2 ON t1.Value = t2.DESC
          WHERE t1.UPDATETYPE='blah')
 SET t1.Value= t2.CODE
8 голосов
/ 05 апреля 2017

Не используйте некоторые ответы выше.

Некоторые предполагают использование вложенного SELECT, не делайте этого, это мучительно медленно. Если вам нужно обновить много записей, используйте объединение, например что-то вроде:

update (select bonus 
        from employee_bonus b 
        inner join employees e on b.employee_id = e.employee_id 
        where e.bonus_eligible = 'N') t
set t.bonus = 0;

Смотрите эту ссылку для более подробной информации. http://geekswithblogs.net/WillSmith/archive/2008/06/18/oracle-update-with-join-again.aspx.

Также убедитесь, что во всех таблицах, к которым вы присоединяетесь, есть первичные ключи.

7 голосов
/ 14 января 2016

Как указано здесь , общий синтаксис для первого решения, предложенного Тони Эндрюсом:

update some_table s
set   (s.col1, s.col2) = (select x.col1, x.col2
                          from   other_table x
                          where  x.key_value = s.key_value
                         )
where exists             (select 1
                          from   other_table x
                          where  x.key_value = s.key_value
                         )

Я думаю, это интересно, особенно если вы хотите обновить более одного поля.

3 голосов
/ 24 января 2013

Этот следующий синтаксис работает для меня.

UPDATE
(SELECT A.utl_id,
    b.utl1_id
    FROM trb_pi_joint A
    JOIN trb_tpr B
    ON A.tp_id=B.tp_id Where A.pij_type=2 and a.utl_id is null
)
SET utl_id=utl1_id;
2 голосов
/ 04 сентября 2015

отлично работает оракул

merge into table1 t1
using (select * from table2) t2
on (t1.empid = t2.empid)
when matched then update set t1.salary = t2.salary
1 голос
/ 15 марта 2010

Использование описание вместо desc для table2,

update
  table1
set
  value = (select code from table2 where description = table1.value)
where
  exists (select 1 from table2 where description = table1.value)
  and
  table1.updatetype = 'blah'
;
0 голосов
/ 19 февраля 2019

Просто для полноты и из-за того, что мы говорим об Oracle, это также может быть сделано:

declare
begin
  for sel in (
    select table2.code, table2.desc
    from table1
    join table2 on table1.value = table2.desc
    where table1.updatetype = 'blah'
  ) loop
    update table1 
    set table1.value = sel.code
    where table1.updatetype = 'blah' and table1.value = sel.desc;    
  end loop;
end;
/
...