Oracle相关更新

发布于 2024-11-30 05:18:13 字数 955 浏览 1 评论 0原文

我在使用 Oracle 10g 语法进行相关更新时遇到困难。我正在 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

等效的 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
        )

这实际上运行子查询两次吗?还有比这更缩写的语法吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

篱下浅笙歌 2024-12-07 05:18:13

至于子查询是否运行两次,使用EXPLAIN PLAN。

我喜欢使用 merge 命令而不是 update 来进行这些相关的更新,例如:(未经测试,如果您想要经过测试的答案,请提供 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 可以将其与有问题的表联系起来。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文