简体   繁体   English

如何使用 Oracle 中的 CTE 更新表

[英]How to update a table using a CTE in Oracle

As an example in Sql server I can achieve this easily like so:作为 Sql 服务器中的示例,我可以像这样轻松地实现这一点:

WITH cte_person AS
(
     SELECT PersonalIdentificationNumber, PersonName
     FROM Employee
)
UPDATE Person
SET Person.PersonName = cte.PersonName
FROM cte_person cte
WHERE Person.PersonalIdentificationNumber = cte.PersonalIdentificationNumber

But how do I achieve this in Oracle using a CTE specifically or is there no support for this?但是我如何在 Oracle 中专门使用 CTE 实现这一点,或者不支持这一点? I have searched around and havn't found a satisfying answer.我四处寻找并没有找到令人满意的答案。 Most seem to wrap the CTE in an inline select statement.大多数似乎都将 CTE 包含在内联 select 语句中。

Oracle does not allow for directly updating a CTE (unlike SQL Server, which allows it). Oracle 不允许直接更新 CTE(与允许它的 SQL 服务器不同)。 If I understand your requirement correctly, you want to update the names in the Person table using the names from the Employee table, based on matching IDs.如果我正确理解您的要求,您希望根据匹配的 ID 使用Employee表中的名称更新Person表中的名称。 One way to do this in Oracle uses a correlated subquery.在 Oracle 中执行此操作的一种方法是使用相关子查询。

UPDATE Person p
SET Name = (SELECT e.Name FROM Employee e
            WHERE e.PersonalIdentificationNumber = p.PersonalIdentificationNumber);

Well, as you asked how to use a CTE in UPDATE , then:好吧,当您询问如何在UPDATE中使用 CTE 时,然后:

update person p set
  p.name = (with cte_person as
              (select personalidentificationnumber, name
               from employee
              )
            select c.name
            from cte_person c
            where c.personalidentificationnumber = p.personalidentificationnumber
           )
  where exists (select null
                from employee e
                where e.personalidentificationnumber = p.personalidentificationnumber
               );

Though, merge is somewhat simpler as you don't have to additionally check which rows to update (see the exists clause in update example):不过, merge稍微简单一些,因为您不必另外检查要更新的行(请参阅update示例中的exists子句):

merge into person p
  using (with cte_person as
              (select personalidentificationnumber, name
               from employee
              )
         select c.personalidentificationnumber,
                c.name
         from cte_person c
        ) x
  on (p.personalidentificationnumber = x.personalidentificationnumber)
  when matched then update set 
    p.name = x.name;        

However, this can be simplified - see code Ankit posted (but - as I said - if you want to know how to use a CTE, then that's how).但是,这可以简化 - 请参阅 Ankit 发布的代码(但是 - 正如我所说 - 如果您想知道如何使用 CTE,那么就是这样)。

You can use MERGE statement for this -您可以为此使用 MERGE 语句 -

MERGE INTO Person p
USING Employee e
ON (p.PersonalIdentificationNumber = e.PersonalIdentificationNumber)
WHEN MATCHED THEN
             UPDATE
                SET p.Name = e.Name;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM