2011-08-18 53 views
3

我在使用Oracle 10g語法進行關聯更新時遇到困難。我正在PL/SQL過程中處理此代碼。Oracle關聯更新

我會在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,因此在這些SQL產品之間具有高度的可移植性。 – onedaywhen

回答

5

至於子查詢是否運行兩次,請使用EXPLAIN PLAN。

我喜歡用的,而不是更新這些相關的更新合併命令,像:(沒有測試,如果你想有一個測試的回答,請提供DDL和insert語句。)

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可以將其綁定回有問題的表。