Oracle相关UPDATE

cra*_*aig 3 sql sql-server plsql oracle10g correlated-subquery

我对Oracle 10g语法的相关UPDATE有困难.我正在PL/SQL过程中处理此代码.

我会在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
Run Code Online (Sandbox Code Playgroud)

等效的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
        )
Run Code Online (Sandbox Code Playgroud)

这实际上是运行子查询两次吗?是否有比此更简短的语法?

Sha*_*nce 5

至于子查询是否运行两次,请使用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
Run Code Online (Sandbox Code Playgroud)

有时您可以更新内联视图,例如:

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
Run Code Online (Sandbox Code Playgroud)

内联视图版本并不总是有效.无法在错误上找到infor,但实际上内联视图需要具有Oracle可以绑定到相关表的唯一键.