2011-08-18 6 views
3

У меня возникли трудности с синтаксисом Oracle 10g для коррелированного UPDATE. Я обрабатываю этот код в PL/SQL-процедуре.Oracle соотносится UPDATE

Я хотел бы подойти к решению проблемы в SQL Server, как так:

UPDATE table_a a 
SET  a.prov_id=pn.prov_id, 
     a.step=1 
from (
      SELECT p.prov_id 
      FROM note n 
      INNER JOIN provider p ON n.author_id=p.user_id 
      where n.enc_id=a.enc_id 
      AND  TRUNC(n.note_time)=a.attr_date 
     ) pn 

Эквивалентный синтаксис Oracle является:

UPDATE table_a a 
SET  a.prov_id=(
      SELECT p.prov_id 
      FROM note n 
      INNER JOIN provider p ON n.author_id=p.user_id 
      where n.enc_id=a.enc_id 
      AND  TRUNC(n.note_time)=a.attr_date 
     ), 
     a.step=1 
WHERE EXISTS (
      SELECT * 
      FROM note n 
      INNER JOIN provider p ON n.author_id=p.user_id 
      where n.enc_id=a.enc_id 
      AND  TRUNC(n.note_time)=a.attr_date 
     ) 

ли это на самом деле запустить подзапрос дважды? Есть ли более сокращенный синтаксис, чем этот?

+0

Взгляните на ключевое слово SQL «MERGE»: оно поддерживается как SQL Server, так и Oracle, как на основе стандартного SQL, поэтому очень переносимо между этими продуктами SQL. – onedaywhen

ответ

5

Что касается запроса, выполняемого дважды, используйте EXPLAIN PLAN.

Мне нравится использовать команду слияния вместо обновления для этих коррелированных обновлений, что-то вроде: (Не тестировался, если вы хотите проверенный ответ, пожалуйста, предоставьте DDL и вставить заявления.)

merge into table_a TRGT 
using (select P.prov_id, N.enc_id, trunc(n.note_time) as trunc_note_time 
    from note N 
    inner join provider P ON N.author_id=P.user_id) SRC 
on (TRGT.enc_id = SRC.enc_id and TRGT.attr_date = SRC.trunc_note_time) 
when matched then update set prov_id = SRC.prov_id 
    , step = 1 

Иногда вам может обновить встроенный вид, например:

update (select A.prov_id, A.step, P.prov_id as p_prov_id 
    from note N 
    inner join provider P on N.author_id=p.user_id 
    inner join table_a A 
     on N.enc_id=A.enc_id 
     and trunc(N.note_time)=A.attr_date) 
set prov_id = p_prov_id 
    , step = 1 

Версия встроенного просмотра не всегда будет работать. Не удается найти информацию об ошибке, но, по существу, встроенное представление должно иметь уникальный ключ, который Oracle может привязать к рассматриваемым таблицам.