В каком порядке выполненяются выражения в SET запроса MERGE?
В каком порядке происходит выполнение запроса на слияние данных MERGE?
Например:
MERGE INTO SCEHMA.TABLE updtab
USING (SELECT * FROM SOURCE_VIEW) fromtab
ON (updtab.key = fromtab.key)
WHEN MATCHED THEN UPDATE SET
updtab.field_1 = case when (updtab.field_1 is null) then fromtab.val_1 end,
updtab.field_2 = case when (updtab.field_1 is null) then fromtab.val_2 end;
Будут ли оба условия для field_1 is null в SET выполнены сразу, или каждое из них будет выполняться последовательно и второй для field_2 всегда будет неудачным, поскольку field_1 больше не будет NULL после первой строки SET?
Полагаю, что по стандарту SQL выборка всегда выполняется первой. Но это же происходит на этапе обновления, и как в этом случае? Документация не совсем ясна и заставляет задуматься.
Свободный перевод вопроса Order of Evaluation - Merge Queries от участника @Greg
Ответы (1 шт):
Все происходит в рамках одного запроса MERGE. Oracle БД обеспечивает согласованность чтения на уровне запроса, что гарантирует, что данные, возвращаемые одним запросом, зафиксированы и согласованы для одного момента времени. Statement-Level Read Consistency:
Oracle Database always enforces statement-level read consistency, which guarantees that data returned by a single query is committed and consistent for a single point in time.
В данном случае момент времени - это время, когда запрос был "открыт" - время начала выполнения.
Это значит, что field_1 воспринимается всеми частями запроса MERGE с одним и тем же значением до тех пор, пока запрос не завершится. Каждое изменение field_1 в операторе SET запроса не отражается на его текущем значении в других частях запроса.
Within a single transaction, you're correct. In the default read committed isolation level a non-repeatable read is possible. If a SELECT statement is re-run and another transaction has committed data then the data read by your first transaction might be different. The MERGE is a statement, and not a transaction.
Если бы в пределах одной транзакции, то утверждение из вопроса было бы верно. На стандартном уровне изоляции с фиксацией чтения возможно "неповторяющееся чтение". Если запросSELECT выполняется повторно и другая транзакция зафиксировала данные с момента начала первого выполнения, то данные считанные первым и вторым запросом могут отличаться. Но MERGE является запросом, а не транзакцией.
Прим.ред.: пошаговый и воспроизводимый пример, наглядно помогающий понять выше изложенное, уже имеется в ответе на похожий вопрос.