如何在 Oracle 中使用 CTE 更新 table

How to update a table using a CTE in Oracle

作为 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

但是我如何在 Oracle 中专门使用 CTE 实现这一点,或者是否不支持这一点?我四处搜寻,但没有找到令人满意的答案。大多数似乎将 CTE 包装在一个内联 select 语句中。

您可以为此使用 MERGE 语句 -

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

Oracle 不允许直接更新 CTE(不像 SQL 服务器,后者允许)。如果我正确理解您的要求,您希望根据匹配的 ID 使用 Employee table 中的名称更新 Person table 中的名称。在 Oracle 中执行此操作的一种方法是使用相关子查询。

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

好吧,正如您在 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
               );

不过,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;        

但是,这可以简化 - 请参阅 Ankit 发布的代码(但是 - 正如我所说 - 如果您想知道如何使用 CTE,那就是这样)。