#sql #oracle #oracle12c
Вопрос:
В качестве примера в Sql server я могу легко добиться этого, вот так:
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.
Комментарии:
1. Oracle не разрешает этот синтаксис. Пожалуйста, предоставьте примеры данных, желаемые результаты и объяснение того, что должен делать код. Примечание: Ваш код также не является допустимым кодом SQL Server, поэтому совершенно неясно, что вы пытаетесь сделать.
Ответ №1:
Ну, поскольку вы спросили , как использовать CTE в UPDATE
, то:
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
это несколько проще, так как вам не нужно дополнительно проверять, какие строки следует обновлять (см. exists
Предложение в update
примере).:
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, то вот как).
Комментарии:
1. Рад видеть последнюю строчку вашего ответа. Это много значит.
2. В то время как ответ Анкита в данном случае действительно проще. Вопрос в том, как конкретно это сделать с CTE, чего, к сожалению, он не сделал. Я рад, что вы нашли время, чтобы тщательно прочитать вопрос, я проверю это, и если он работает так, как ожидалось, и для этого нет более чистого синтаксиса, вы также получите ответ.
Ответ №2:
Oracle не позволяет напрямую обновлять CTE (в отличие от SQL Server, который это позволяет). Если я правильно понимаю ваше требование, вы хотите обновить имена в Person
таблице, используя имена из Employee
таблицы, на основе совпадающих идентификаторов. Один из способов сделать это в Oracle использует коррелированный подзапрос.
UPDATE Person p
SET Name = (SELECT e.Name FROM Employee e
WHERE e.PersonalIdentificationNumber = p.PersonalIdentificationNumber);
Комментарии:
1. Спасибо за ваш вклад. Я дал вам указание указать, что Oracle не поддерживает этот синтаксис, но вопрос в том, как использовать CTE.
Ответ №3:
Для этого вы можете использовать инструкцию MERGE —
MERGE INTO Person p
USING Employee e
ON (p.PersonalIdentificationNumber = e.PersonalIdentificationNumber)
WHEN MATCHED THEN
UPDATE
SET p.Name = e.Name;
Комментарии:
1. Спасибо за ваш вклад, Анкит, но я уже знаю о синтаксисе слияния сам по себе. Вопрос заключался в том, как это сделать с помощью CTE.
2. «Вопрос заключался в том, как это сделать с помощью CTE». Мне любопытно, почему настаивают на использовании CTE, когда есть лучшие решения.