2011-08-18 14 views
3

相関UPDATEのOracle 10gの構文に問題があります。私はこのコードを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の両方でサポートされています(両方ともStandard SQLに基づいているため、これらのSQL製品間で移植性が高い)。 – onedaywhen

答えて

5

サブクエリが2回実行されるかどうかについては、EXPLAIN PLANを使用します。私は、これらの相関の更新のための代わりに、更新のようなものmergeコマンドを使用したい

:(あなたがテストした答えをしたい場合はテストしていないが、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が問題の表に結びつけることができる一意のキーが必要です。