Открыть сервис

Оператор MERGE

Оператор MERGE — это оператор языка SQL, относящийся к категории DML (Data Manipulation Language), который позволяет выполнять операции вставки (INSERT), обновления (UPDATE) и удаления (DELETE) в одной инструкции на основе сравнения исходных данных с данными целевой таблицы. Оператор также известен как «upsert» (от англ. update + insert) и применяется для синхронизации содержимого двух таблиц или для условного обновления записей с возможностью их добавления при отсутствии.

История и стандартизация

Концепция операции, объединяющей вставку и обновление, существовала в различных СУБД задолго до формальной стандартизации. В 1999 году оператор MERGE был включён в стандарт SQL:1999 (ISO/IEC 9075:1999) как часть расширения языка для работы с данными. Однако ранние реализации, такие как команда MERGE в Oracle Database (появилась в версии 9i, выпущенной в 2001 году), отличались от более позднего стандарта.

В последующих версиях стандарта — SQL:2003, SQL:2008, SQL:2011 и SQL:2016 — синтаксис и семантика оператора были уточнены, в частности, добавлена возможность выполнения операций DELETE в рамках MERGE и уточнены правила обработки дублирующихся строк. В настоящее время оператор MERGE поддерживается большинством реляционных СУБД, включая Oracle Database, Microsoft SQL Server (начиная с версии 2008), PostgreSQL (с версии 9.5), IBM Db2, SAP HANA, а также в ограниченном виде — в MySQL (через конструкцию INSERT ... ON DUPLICATE KEY UPDATE) и SQLite (через INSERT OR REPLACE или UPSERT).

Синтаксис

Общий синтаксис оператора MERGE в соответствии со стандартом SQL:2008 выглядит следующим образом:

``sql MERGE INTO target_table AS target USING source_table AS source ON condition WHEN MATCHED THEN UPDATE SET column1 = value1, column2 = value2, ... WHEN NOT MATCHED THEN INSERT (column1, column2, ...) VALUES (value1, value2, ...) WHEN NOT MATCHED BY SOURCE THEN DELETE; ``

Ключевые элементы синтаксиса

В некоторых реализациях (например, в Oracle) поддерживается также клаузула WHEN NOT MATCHED THEN INSERT без обязательного указания BY SOURCE, а также возможность указания LOG ERRORS для обработки ошибок.

Примеры использования

Пример 1: базовая синхронизация таблиц

Пусть имеется таблица employees (целевая) и таблица new_employees (источник). Необходимо обновить данные существующих сотрудников и добавить новых.

``sql MERGE INTO employees AS e USING new_employees AS n ON e.employee_id = n.employee_id WHEN MATCHED THEN UPDATE SET e.salary = n.salary, e.department = n.department WHEN NOT MATCHED THEN INSERT (employee_id, name, salary, department) VALUES (n.employee_id, n.name, n.salary, n.department); ``

Пример 2: удаление отсутствующих записей

Если требуется также удалить из целевой таблицы записи, которых нет в источнике, добавляется клаузула WHEN NOT MATCHED BY SOURCE:

``sql MERGE INTO employees AS e USING new_employees AS n ON e.employee_id = n.employee_id WHEN MATCHED THEN UPDATE SET e.salary = n.salary, e.department = n.department WHEN NOT MATCHED THEN INSERT (employee_id, name, salary, department) VALUES (n.employee_id, n.name, n.salary, n.department) WHEN NOT MATCHED BY SOURCE THEN DELETE; ``

Особенности и ограничения

Производительность

Оператор MERGE является атомарным — все изменения выполняются в рамках одной транзакции, что снижает накладные расходы на передачу данных между клиентом и сервером по сравнению с последовательным выполнением отдельных операций INSERT, UPDATE и DELETE. Однако при работе с большими объёмами данных может потребоваться настройка плана выполнения, так как некоторые СУБД (например, SQL Server) могут генерировать неоптимальные планы для MERGE.

Конфликты и дублирование

При использовании MERGE важно, чтобы условие ON однозначно идентифицировало строки. Если в источнике или цели есть дублирующиеся строки по условию соединения, возникает конфликт, который может привести к ошибке. Стандарт SQL:2008 требует, чтобы каждая строка цели соединялась не более чем с одной строкой источника; в противном случае СУБД генерирует исключение.

Обработка ошибок

Некоторые СУБД (например, Oracle) предоставляют возможность логирования ошибок с помощью клаузулы LOG ERRORS, что позволяет продолжить выполнение MERGE даже при возникновении ошибок в отдельных строках. В других СУБД (например, PostgreSQL) для обработки ошибок может потребоваться использование блоков EXCEPTION в хранимых процедурах.

Различия в реализациях

Альтернативы

В СУБД, не поддерживающих MERGE, или в случаях, когда его использование нежелательно (например, из-за проблем с производительностью), применяются следующие подходы:

Применение

Оператор MERGE широко используется в следующих сценариях:

Критика

Несмотря на широкое распространение, оператор MERGE подвергается критике по нескольким причинам:

Источники

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →