Question

I'm having difficulty with Oracle 10g syntax for a correlated UPDATE. I am processing this code in a PL/SQL procedure.

I would approach the problem in SQL Server as so:

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

The equivalent Oracle syntax is:

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
        )

Does this in fact run the sub-query twice? Is there a more-abbreviated syntax than this?

Was it helpful?

Solution

As to whether the sub-query runs twice, use EXPLAIN PLAN.

I like to use the merge command instead of update for these correlated updates, something like: (Not tested, if you want a tested answer, please provide DDL and insert statements.)

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

Sometimes you can update an inline view, something like:

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

The inline view version won't always work. Can't find infor on the error, but essentially the inline view needs to have a unique key that Oracle can tie back to the tables in question.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top