Синтаксис оператора Merge

SQL_Deep_3.07_site-5020-ffa604.png

Merge относится к DML (Data Manipulation Language) языка SQL. Оператор появился с версии SQL Server 2008 и используется для того, чтобы привести 2 набора данных в соответствие — добавить строки, если их нет, обновить, если строки найдены, и удалить (опционально).

Merge можно использовать не только для того, чтобы сделать вставку или изменение данных, но с точки зрения производительности выгоднее будет вызывать классические Insert или Update.

Сразу хочу сказать, что синтаксис приводится в упрощённом варианте, чтобы сначала изучить базовую функциональность, а потом уже погружаться глубже.

MERGE <target_table> [AS TARGET]
USING <table_source> [AS SOURCE]
ON <search_condition>
[WHEN MATCHED 
THEN <merge_matched> ]
[WHEN NOT MATCHED [BY TARGET]
THEN <merge_not_matched> ]
[WHEN NOT MATCHED BY SOURCE
THEN <merge_matched> ]
[OUTPUT];

Разберём каждую часть

Target table — целевая таблица, именно в ней данные будут добавлены, изменены или удалены в результате выполнения оператора.

Source table — исходная таблица или таблица-источник данных, с которой будет сравниваться целевая таблица, это может быть любой набор данных. Предложение USING напоминает предложение FROM из оператора SELECT, тут можно указать таблицу, подзапрос, табличное выражение или функцию, возвращающую таблицу.

Далее ON — условие соединения двух таблиц (а точнее, наборов данных), такое же как ON в JOIN.

Теперь посмотрим на соотношение

1-20219-3f0845.png

Следующие 3 части оператора

When Matched — описывает действие, которое срабатывает для строк, которые нашлись и в Source, и в Target по условию, которое описано в ON. В этой части чаще всего встречается оператор UPDATE, хотя возможно использование оператора DELETE.

When Not Matched [By Target] — описывает действие для строк, которые есть в таблице Source, но отсутствуют в таблице Target; далее используется оператор INSERT, и указанные строки добавляются в таблицу Target.

When Not Matched By Source — описывает действие для строк, которые отсутствуют в таблице Source, но найдены в таблице Target, чаще всего встречается оператор DELETE, чтобы удалить строки и привести 2 набора в соответствие, но возможно использование оператора Update.

Если переложить на оператор, то получится:

2-20219-9c1b15.pngНапример, возьмём загрузку данных о наличие книг:

3-20219-1f0f73.pngСтроки 1 и 2 — произойдёт Update, строки 3 и 4 — Insert, а строка 5 — из таблицы Target будет удалена Delete.

И последняя часть оператора в примере

OUTPUT — отличается тем, что есть специальная функция $action, которая возвращает оператор, который был применён для конкретной строки. Служебные таблицы deleted показывают данные, которые были в Target до выполнения Merge. Inserted — данные, которые возникли после применения Merge.

Ниже пример кода с Merge:

CREATE TABLE BooksSalesStat
    (BookId BIGINT PRIMARY KEY,
     BookName VARCHAR(128),
     SalesCount INT);

CREATE TABLE StagingBooksSalesStat
    (BookId BIGINT PRIMARY KEY,
     BookName VARCHAR(128),
     SalesCount INT);

INSERT INTO BooksSalesStat
(BookId, BookName, SalesCount)
VALUES
(1,'Остров Сокровищ', 4),
(2,'Незнайка', 5),
(5,'Алые паруса', 2);

INSERT INTO StagingBooksSalesStat
(BookId, BookName, SalesCount)
VALUES
(1,'Остров Сокровищ', 4),
(2,'Незнайка', 5),
(3,'Робинзон Крузо', 10),
(4,'Руслан и Людмила', 12);


MERGE BooksSalesStat AS Target
USING StagingBooksSalesStat AS Source
    ON (Target.BookId = Source.BookId)
WHEN MATCHED 
    THEN UPDATE 
        SET SalesCount = Source.SalesCount
WHEN NOT MATCHED 
    THEN INSERT 
        VALUES (Source.BookId, Source.BookName, Source.SalesCount)
WHEN NOT MATCHED BY SOURCE
    THEN 
        DELETE
OUTPUT deleted.*, $action, inserted.*;

Что можно почитать по Merge: 1. Ben-Gan I., Sarka D., Talmage R. — Training Kit (Exam 70-461) Querying Microsoft SQL Server 2012-2012, Глава 11. 2. Документация. 3. Статья.

Есть вопрос? Напишите в комментариях!

Автор
0 комментариев
Для комментирования необходимо авторизоваться