Merge (SQL)
Реляційні системи керування базами даних використовують оператори SQL MERGE
(також звані upsert) для вставляння нових записів або оновлення наявних залежно від збігів за умовою[en]. Цей оператор було офіційно впроваджено у стандарті SQL:2003 та розширено у стандарті SQL:2008.
MERGE INTO tablename USING table_reference
ON (condition)
WHEN MATCHED THEN
UPDATE
SET column1 = value1 [, column2 = value2 ...]
WHEN NOT MATCHED THEN
INSERT (column1 [, column2 ...])
VALUES (value1 [, value2 ...]);
До цілі (таблиця INTO
) та джерела (таблиця, розріз або підзапит USING
) застосовується праве зовнішнє з'єднання, в якому ціль є лівою таблицею, а джерело — правою. Чотири можливі комбінації відповідають таким правилам:
- Якщо поля
ON
у джерелі збігаються з полямиON
у цілі, тоUPDATE
- Якщо поля
ON
у джерелі не збігаються з полямиON
у цілі, тоINSERT
- Якщо полів
ON
не існує у джерелі, але є в цілі, то нічого не відбувається. - Якщо полів
ON
не існує ані в джерелі ані в цілі, то нічого не відбувається.
Якщо кілька рядків у джерелі відповідають одному рядкові в цілі, то, згідно стандарту SQL:2003, виникає помилка. Оновлювати рядки в цілі за допомогою оператора MERGE
декілька разів не можна.
Системи керування базами даних Oracle Database, DB2, Teradata, EXASOL[en], Firebird, CUBRID[en], HSQLDB, MS SQL, Vectorwise[en], Apache Derby[en] та BigQuery[1] підтримують стандартний синтаксис. Деякі також додають нестандартні розширення SQL.
В деяких реалізаціях баз даних для операторів або їх комбінацій, що вставляють запис до таблиці бази даних, якщо його не існує, або ж оновлюють наявний запис, було обрано термін «Upsert» (словозлиття update та insert). Його також застосовують як скорочений варіант запису MERGE
у псевдокоді.
Він використовується в Microsoft SQL Azure.[2]
Деякі інші системи керування базами даних підтримують таку ж або дуже схожу поведінку за допомогою власних, нестандартних розширень SQL.
MySQL, наприклад, підтримує використання синтаксису INSERT ... ON DUPLICATE KEY UPDATE
,[3] який можна використовувати для досягнення схожого ефекту, з тим обмеженням, що з'єднання між ціллю та джерелом має відбуватися винятково за примусів PRIMARY KEY
чи UNIQUE
, чого не вимагає стандарт ANSI/ISO. Вона також підтримує синтаксис REPLACE INTO
,[4] який спочатку намагається вставити, а у разі невдачі видаляє рядок, якщо той існує, та вставляє новий. Існує також вираз IGNORE
для оператора INSERT
,[5] що каже серверу ігнорувати помилки «дублікат ключа» та продовжувати (наявні рядки не вставлятимуться й не оновлюватимуться, але всі нові вставлятимуться).
Подібним чином працює INSERT OR REPLACE INTO
в SQLite. Він також підтримує REPLACE INTO
як псевдонім для сумісності з MySQL.[6]
Firebird підтримує MERGE INTO
, хоча й не може видавати помилку, коли джерело містить кілька рядків. Крім того, існує однорядковий варіант UPDATE OR INSERT INTO tablename (columns) VALUES (values) [MATCHING (columns)]
, але він не дозволяє виконувати різні дії при вставці чи оновленні (наприклад, встановлення нового значення послідовності лише для нових записів, а не наявних).
IBM DB2 розширює синтаксис кількома виразами WHEN MATCHED
і WHEN NOT MATCHED
, розрізняючи їх вартами ... AND some-condition
.
Microsoft SQL Server розширюється підтримкою варт, а також підтримкою лівого зовнішнього з'єднання за допомогою виразів WHEN NOT MATCHED BY SOURCE
.
PostgreSQL підтримує злиття за допомогою INSERT INTO ... ON CONFLICT [ conflict_target ] conflict_action
.[7]
CUBRID[en] підтримує оператор MERGE INTO
,[8] використання синтаксису INSERT ... ON DUPLICATE KEY UPDATE
,[9] а також REPLACE INTO
для сумісності з MySQL.[10]
Apache Phoenix[en] підтримує синтаксис UPSERT VALUES
[11] і UPSERT SELECT
.[11]
- ↑ Data Manipulation Language Syntax | BigQuery. Google Cloud. Архів оригіналу за 4 квітня 2019. Процитовано 13 березня 2019.
- ↑ MERGE (Transact-SQL). Transact-SQL Reference (Database Engine) (англійською) . Мережа розробників Майкрософт. Архів оригіналу за 11 листопада 2016. Процитовано 27 грудня 2016.
- ↑ INSERT ... ON DUPLICATE KEY UPDATE Syntax. MySQL 5.7 Reference Manual (англійською) . Архів оригіналу за 28 грудня 2016. Процитовано 27 грудня 2016.
- ↑ REPLACE Syntax. MySQL 5.7 Reference Manual (англійською) . Архів оригіналу за 28 грудня 2016. Процитовано 27 грудня 2016.
- ↑ INSERT Syntax. MySQL 5.5 Reference Manual (англійською) . Архів оригіналу за 24 жовтня 2013. Процитовано 29 жовтня 2013.
- ↑ SQL As Understood By SQLite: INSERT. SQLite (англійською) . Архів оригіналу за 23 вересня 2012. Процитовано 27 вересня 2012.
- ↑ INSERT. PostgreSQL: Documentation: 9.6 (англійською) . Архів оригіналу за 28 грудня 2016. Процитовано 27 грудня 2016.
- ↑ Сагінов, Есен (30 жовтня 2012). Announcing CUBRID 9.0 with 3x performance increase and Sharding support (англійською) . CUBRID Official Blog. Архів оригіналу за 5 листопада 2012. Процитовано 8 листопада 2012.
- ↑ INSERT. CUBRID 10.0.0 Documentation (англійською) . Архів оригіналу за 7 жовтня 2016. Процитовано 27 грудня 2016.
- ↑ String Functions and Operators. CUBRID 10.0.0 Documentation (англійською) . Архів оригіналу за 7 жовтня 2016. Процитовано 27 грудня 2016.
- ↑ а б Grammar. Apache Phoenix[en] (англійською) . Архів оригіналу за 27 грудня 2016. Процитовано 27 грудня 2016.
- Хсу, Лео; Обе, Регіна (18 травня 2008). Cross Compare of SQL Server, MySQL, and PostgreSQL. Postgres OnLine Journal. Архів оригіналу за 26 листопада 2010. Процитовано 8 жовтня 2010.
- Чодоров, Крістіна; Діролф, Майк (вересень 2010). MongoDB: The Definitive Guide. O'Reilly Media. ISBN 978-1-449-38156-1.