В Oracle вы можете обновить подзапрос уплотнительное если Oracle сможет точно определить одну и ту же строку базовой таблицы для каждой строки подзапроса. Кроме того, additional restrictions apply относительно использования функции аналитика, агрегатов и т.д.
В вашем примере DISTINCT
сделает Oracle удалось обновить вложенный запрос, потому что один строка подзапроса может указывать на несколько строк базовой таблицы ,
Если удалить DISTINCT
, запрос будет работать, только если есть уникальный индекс на MATERIAL(item_id)
так, что каждая строка в таблице POLINE
могут быть связаны только с не более одной строки в MATERIAL
:
UPDATE (SELECT a.item_id, a.account_code acct_a,
b.item_id, b.account_code acct_b
FROM bp.poline a, mt.material b
WHERE a.item_id = b.item_id
AND a.account_code IS NOT NULL
AND b.account_code IS NULL)
SET acct_a = acct_b
Обновление соединения очень эффективно, но имеет несколько ограничений, что, если у вас нет этого индекса?
Вы можете написать стандартное обновление с другим подзапросом:
UPDATE poline a
SET a.account_code = (SELECT b.account_code
FROM material b
WHERE b.item_id = a.item_id
AND b.account_code is not null)
WHERE a.account_code IS NULL
AND a.item_id IN (SELECT b.item_id
FROM material b
WHERE b.account_code IS NOT NULL)
Самым элегантным решением ИМО, однако, вдохновленный answer to a similar question, будет:
MERGE INTO (SELECT * FROM a WHERE account_code IS NULL) a
USING (SELECT * FROM b WHERE account_code IS NOT NULL) b
ON (a.item_id = b.item_id)
WHEN MATCHED THEN UPDATE SET a.account_code = b.account_code;
Не это означает, что ' account_code' не является полем в вашем псевдониме 'a'? –
account_code существует в a. Я это проверил. – cooldude
См. Этот вопрос: [Oracle - инструкция обновления с внутренним соединением] (http://stackoverflow.com/q/2446764/851811). –