Merge (SQL)

Матеріал з Вікіпедії — вільної енциклопедії.
Перейти до навігації Перейти до пошуку

Реляційні системи керування базами даних використовують оператори SQL MERGE (також звані upsert) для вставляння нових записів або оновлення наявних залежно від збігів за умовою[en]. Цей оператор було офіційно впроваджено у стандарті SQL:2003 та розширено у стандарті SQL:2008[en].

Застосування[ред. | ред. код]

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[en], 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]

Див. також[ред. | ред. код]

Примітки[ред. | ред. код]

  1. Data Manipulation Language Syntax | BigQuery. Google Cloud. Процитовано 2019-03-13. 
  2. MERGE (Transact-SQL). Transact-SQL Reference (Database Engine) (англійською). Мережа розробників Майкрософт. Процитовано 27 грудня 2016. 
  3. INSERT ... ON DUPLICATE KEY UPDATE Syntax. MySQL 5.7 Reference Manual (англійською). Процитовано 27 грудня 2016. 
  4. REPLACE Syntax. MySQL 5.7 Reference Manual (англійською). Процитовано 27 грудня 2016. 
  5. INSERT Syntax. MySQL 5.5 Reference Manual (англійською). Процитовано 29 жовтня 2013. 
  6. SQL As Understood By SQLite: INSERT. SQLite (англійською). Процитовано 27 вересня 2012. 
  7. INSERT. PostgreSQL: Documentation: 9.6 (англійською). Процитовано 27 грудня 2016. 
  8. Сагінов, Есен (30 жовтня 2012). Announcing CUBRID 9.0 with 3x performance increase and Sharding support (англійською). CUBRID Official Blog. Процитовано 8 листопада 2012. 
  9. INSERT. CUBRID 10.0.0 Documentation (англійською). Процитовано 27 грудня 2016. 
  10. String Functions and Operators. CUBRID 10.0.0 Documentation (англійською). Процитовано 27 грудня 2016. 
  11. а б Grammar. Apache Phoenix[en] (англійською). Процитовано 27 грудня 2016. 

Література[ред. | ред. код]

Посилання[ред. | ред. код]