Merge синтаксис oracle: Oracle PL/SQL оператор MERGE — Oracle PL/SQL •MySQL •MariaDB •SQL Server •SQLite
Содержание
Oracle10gr1 ora-28132 The MERGE INTO syntax does not support the security policy.
База данных: 10g Выпуск 1
Код ошибки: ORA-28132
Описание: Синтаксис MERGE INTO не поддерживает политику защиты.
Причина: Синтаксис MERGE INTO не поддерживает политику безопасности для таблицы назначения, потому что в параметрах policy_types политики не было каждого из INSERT, UPDATE и DELETE.
Действие: Если у вас нет прав изменять политику безопасности, вместо MERGE INTO используйте операторы INSERT, UPDATE и DELETE DML для таблицы, для которой определена политика безопасности. Если у вас есть право изменять политику безопасности, переопределите ее таким образом, чтобы в Statement_types были включены все типы операторов DML (INSERT, UPDATE и DELETE).
База данных: 10g Выпуск 1
Код ошибки: ORA-28132
Описание: Merge into syntax does not support security policies.
Причина: Merge into syntax currently does not support a security policy on the destination table.
Действие: use the insert / update DML stmts on the table that has a security policy defined on it.
База данных: 10g Выпуск 2
Код ошибки: ORA-28132
Описание: Синтаксис MERGE INTO не поддерживает политику защиты.
Причина: Синтаксис MERGE INTO не поддерживает политику безопасности для таблицы назначения, потому что в параметрах policy_types политики не было каждого из INSERT, UPDATE и DELETE.
Действие: Если у вас нет прав изменять политику безопасности, вместо MERGE INTO используйте операторы INSERT, UPDATE и DELETE DML для таблицы, для которой определена политика безопасности. Если у вас есть право изменять политику безопасности, переопределите ее таким образом, чтобы в Statement_types были включены все типы операторов DML (INSERT, UPDATE и DELETE).
База данных: 11g Выпуск 1
Код ошибки: ORA-28132
Описание: Синтаксис MERGE INTO не поддерживает политику защиты.
Причина: Синтаксис MERGE INTO не поддерживает политику безопасности для таблицы назначения, потому что в параметрах policy_types политики не было каждого из INSERT, UPDATE и DELETE.
Действие: Если у вас нет прав изменять политику безопасности, вместо MERGE INTO используйте операторы INSERT, UPDATE и DELETE DML для таблицы, для которой определена политика безопасности. Если у вас есть право изменять политику безопасности, переопределите ее таким образом, чтобы в Statement_types были включены все типы операторов DML (INSERT, UPDATE и DELETE).
База данных: 11g Выпуск 2
Код ошибки: ORA-28132
Описание: Синтаксис MERGE INTO не поддерживает политику защиты.
Причина: Синтаксис MERGE INTO не поддерживает политику безопасности для таблицы назначения, потому что в параметрах policy_types политики не было каждого из INSERT, UPDATE и DELETE.
Действие: Если у вас нет прав изменять политику безопасности, вместо MERGE INTO используйте операторы INSERT, UPDATE и DELETE DML для таблицы, для которой определена политика безопасности. Если у вас есть право изменять политику безопасности, переопределите ее таким образом, чтобы в Statement_types были включены все типы операторов DML (INSERT, UPDATE и DELETE).
База данных: 12c Выпуск 1
Код ошибки: ORA-28132
Описание: Синтаксис MERGE INTO не поддерживает политику защиты.
Причина: Синтаксис MERGE INTO не поддерживает политику безопасности для таблицы назначения, потому что в параметрах policy_types политики не было каждого из INSERT, UPDATE и DELETE.
Действие: Если у вас нет прав изменять политику безопасности, вместо MERGE INTO используйте операторы INSERT, UPDATE и DELETE DML для таблицы, для которой определена политика безопасности. Если у вас есть право изменять политику безопасности, переопределите ее таким образом, чтобы в Statement_types были включены все типы операторов DML (INSERT, UPDATE и DELETE).
База данных: 12c Выпуск 2
Код ошибки: ORA-28132
Описание: Синтаксис MERGE INTO не поддерживает политику защиты.
Причина: Синтаксис MERGE INTO не поддерживает политику безопасности для таблицы назначения, потому что в параметрах policy_types политики не было каждого из INSERT, UPDATE и DELETE.
Действие: Если у вас нет прав изменять политику безопасности, вместо MERGE INTO используйте операторы INSERT, UPDATE и DELETE DML для таблицы, для которой определена политика безопасности. Если у вас есть право изменять политику безопасности, переопределите ее таким образом, чтобы в Statement_types были включены все типы операторов DML (INSERT, UPDATE и DELETE).
База данных: 18c Выпуск 1
Код ошибки: ORA-28132
Описание: Синтаксис MERGE INTO не поддерживает политику защиты.
Причина: Синтаксис MERGE INTO не поддерживает политику безопасности для таблицы назначения, потому что в параметрах policy_types политики не было каждого из INSERT, UPDATE и DELETE.
Действие: Если у вас нет прав изменять политику безопасности, вместо MERGE INTO используйте операторы INSERT, UPDATE и DELETE DML для таблицы, для которой определена политика безопасности. Если у вас есть право изменять политику безопасности, переопределите ее таким образом, чтобы в Statement_types были включены все типы операторов DML (INSERT, UPDATE и DELETE).
База данных: 19c Выпуск 1
Код ошибки: ORA-28132
Описание: Синтаксис MERGE INTO не поддерживает политику защиты.
Причина: Синтаксис MERGE INTO не поддерживает политику безопасности для таблицы назначения, потому что в параметрах policy_types политики не было каждого из INSERT, UPDATE и DELETE.
Действие: Если у вас нет прав изменять политику безопасности, вместо MERGE INTO используйте операторы INSERT, UPDATE и DELETE DML для таблицы, для которой определена политика безопасности. Если у вас есть право изменять политику безопасности, переопределите ее таким образом, чтобы в Statement_types были включены все типы операторов DML (INSERT, UPDATE и DELETE).
Библиотека кодов ошибок базы данных Oracle
- _10gR1 Коды ошибок
- _10gR2 Коды ошибок
- _11gR1 Коды ошибок
- _11gR2 Коды ошибок
- _12cR1 Коды ошибок
- _12cR2 Коды ошибок
- _18cR1 Коды ошибок
- _19cR1 Коды ошибок
Параметры базы данных Oracle
- Список параметров
Пакеты баз данных Oracle
Список пакетов
- Список пакетов
- _Пакеты Oracle Database 12cR1
- _Пакеты Oracle Database 11gR2
- _Пакеты Oracle Database 11gR1
- _Пакеты Oracle Database 10gR2
Словарь данных базы данных Oracle
- _База данных Oracle 10gR2 Словарь данных
- _База данных Oracle 11gR2 Словарь данных
- _База данных Oracle 12cR1 Словарь данных
- _База данных Oracle 12cR2 Словарь данных
- _База данных Oracle 18cR1 Словарь данных
- _База данных Oracle 19cR1 Словарь данных
Операция MERGE в языке Transact-SQL – описание и примеры | Info-Comp.
ru
В языке Transact-SQL в одном ряду с такими операциями как INSERT (вставка), UPDATE (обновление), DELETE (удаление) стоит операция MERGE (слияние), которая в некоторых случаях может быть полезна, но некоторые почему-то о ней не знают и не пользуются ею, поэтому сегодня мы рассмотрим данную операцию и разберем примеры.
Начнем мы, конечно же, с небольшой теории.
Заметка! Начинающим рекомендую посмотреть мой видеокурс по T-SQL.
Содержание
- Что такое MERGE в T-SQL?
- Исходные данные для примеров операции MERGE
- Пример 1 – обновление и добавление данных с помощью MERGE
- Пример 2 – синхронизация таблиц с помощью MERGE
- Пример 3 – операция MERGE с дополнительным условием
Что такое MERGE в T-SQL?
MERGE – операция в языке T-SQL, при которой происходит обновление, вставка или удаление данных в таблице на основе результатов соединения с данными другой таблицы или SQL запроса. Другими словами, с помощью MERGE можно осуществить слияние двух таблиц, т.е. синхронизировать их.
В операции MERGE происходит объединение по ключевому полю или полям основной таблицы (в которой и будут происходить все изменения) с соответствующими полями другой таблицы или результата запроса. В итоге если условие, по которому происходит объединение, истина (WHEN MATCHED), то мы можем выполнить операции обновления или удаления, если условие не истина, т.е. отсутствуют данные (WHEN NOT MATCHED), то мы можем выполнить операцию вставки (INSERT добавление данных), также если в основной таблице присутствуют данные, которое отсутствуют в таблице (или результате запроса) источника (WHEN NOT MATCHED BY SOURCE), то мы можем выполнить обновление или удаление таких данных.
В дополнение к основным перечисленным выше условиям можно указывать «Дополнительные условия поиска», они указываются через ключевое слово AND.
Упрощённый синтаксис MERGE
MERGE <Основная таблица> USING <Таблица или запрос источника> ON <Условия объединения> [ WHEN MATCHED [ AND <Доп. условие> ] THEN <UPDATE или DELETE> [ WHEN NOT MATCHED [ AND Доп. условие> ] THEN <INSERT> ] [ WHEN NOT MATCHED BY SOURCE [ AND <Доп. условие> ] THEN <UPDATE или DELETE> ] [ ...n ] [ OUTPUT ] ;
Важные моменты при использовании MERGE:
- В конце инструкции MERGE обязательно должна идти точка с запятой (;) иначе возникнет ошибка;
- Должно быть, по крайней мере, одно условие MATCHED;
- Операцию MERGE можно использовать совместно с CTE (обобщенным табличным выражением);
- В инструкции MERGE можно использовать ключевое слово OUTPUT, для того чтобы посмотреть какие изменения были внесены. Для идентификации операции здесь в OUTPUT можно использовать переменную $action;
- На все операции к основной таблице, которые предусмотрены в MERGE (удаления, вставки или обновления), действуют все ограничения, определенные для этой таблицы;
- Функция @@ROWCOUNT, если ее использовать после инструкции MERGE, будет возвращать общее количество вставленных, обновленных и удаленных строк;
- Для того чтобы использовать MERGE необходимо разрешение на INSERT, UPDATE или DELETE в основной таблице, и разрешение SELECT для таблицы источника;
- При использовании MERGE необходимо учитывать, что все триггеры AFTER на INSERT, UPDATE или DELETE, определенные для целевой таблицы, будут запускаться.
А теперь переходим к практике. И для начала давайте определимся с исходными данными.
Исходные данные для примеров операции MERGE
У меня в качестве SQL сервера будет выступать Microsoft SQL Server 2016 Express. На нем есть тестовая база данных, в которой я создаю тестовые таблицы, например, с товарами: TestTable – это у нас будет целевая таблица, т. е. та над которой мы будем производить все изменения, и TestTableDop – это таблица источник, т.е. данные в соответствии с чем, мы будем производить изменения.
Запрос для создания таблиц.
--Целевая таблица CREATE TABLE dbo.TestTable( ProductId INT NOT NULL, ProductName VARCHAR(50) NULL, Summa MONEY NULL, CONSTRAINT PK_TestTable PRIMARY KEY CLUSTERED (ProductId ASC) ) --Таблица источник CREATE TABLE dbo.TestTableDop( ProductId INT NOT NULL, ProductName VARCHAR(50) NULL, Summa MONEY NULL, CONSTRAINT PK_TestTableDop PRIMARY KEY CLUSTERED (ProductId ASC) )
Далее я их наполняю тестовыми данными.
--Добавляем данные в основную таблицу INSERT INTO dbo.TestTable (ProductId,ProductName,Summa) VALUES (1, 'Компьютер', 0) GO INSERT INTO dbo. TestTable (ProductId,ProductName,Summa) VALUES (2, 'Принтер', 0) GO INSERT INTO dbo.TestTable (ProductId,ProductName,Summa) VALUES (3, 'Монитор', 0) GO --Добавляем данные в таблицу источника INSERT INTO dbo.TestTableDop (ProductId,ProductName,Summa) VALUES (1, 'Компьютер', 500) GO INSERT INTO dbo.TestTableDop (ProductId,ProductName,Summa) VALUES (2, 'Принтер', 300) GO INSERT INTO dbo.TestTableDop (ProductId,ProductName,Summa) VALUES (4, 'Монитор', 400) GO
Посмотрим на эти данные.
SELECT * FROM dbo.TestTable SELECT * FROM dbo.TestTableDop
Видно, что в целевой таблице значение поля Summa = 0, а также есть несоответствие некоторых идентификаторов, т.е. у нас есть товары, которые есть в одной таблице, при этом они отсутствуют в другой.
Пример 1 – обновление и добавление данных с помощью MERGE
Это, наверное, классический вариант использования MERGE, когда мы по условию объединения обновляем данные, а если таких данных нет, то добавляем их. Для наглядности в конце инструкции MERGE я укажу ключевое слово OUTPUT, для того чтобы посмотреть какие именно изменения мы произвели, а также сделаю выборку итоговых данных.
MERGE dbo.TestTable AS T_Base --Целевая таблица USING dbo.TestTableDop AS T_Source --Таблица источник ON (T_Base.ProductId = T_Source.ProductId) --Условие объединения WHEN MATCHED THEN --Если истина (UPDATE) UPDATE SET ProductName = T_Source. ProductName, Summa = T_Source.Summa WHEN NOT MATCHED THEN --Если НЕ истина (INSERT) INSERT (ProductId, ProductName, Summa) VALUES (T_Source.ProductId, T_Source.ProductName, T_Source.Summa) --Посмотрим, что мы сделали OUTPUT $action AS [Операция], Inserted.ProductId, Inserted.ProductName AS ProductNameNEW, Inserted.Summa AS SummaNEW, Deleted.ProductName AS ProductNameOLD, Deleted.Summa AS SummaOLD; --Не забываем про точку с запятой --Итоговый результат SELECT * FROM dbo.TestTable SELECT * FROM dbo.TestTableDop
Мы видим, что у нас было две операции UPDATE и одна INSERT. Так оно и есть, две строки из таблицы TestTable соответствуют двум строкам в таблице TestTableDop, т.е. у них один и тот же ProductId, у данных строк в таблице TestTable мы обновили поля ProductName и Summa. При этом в таблице TestTableDop есть строка, которая отсутствует в TestTable, поэтому мы ее и добавили через INSERT.
Пример 2 – синхронизация таблиц с помощью MERGE
Теперь, допустим, нам нужно синхронизировать таблицу TestTable с таблицей TestTableDop, для этого мы добавим еще одно условие WHEN NOT MATCHED BY SOURCE, суть его в том, что мы удалим строки, которые есть в TestTable, но нет в TestTableDOP. Но для начала, для того чтобы у нас все три условия отработали (в частности WHEN NOT MATCHED) давайте в таблице TestTable удалим строку, которую мы добавили в предыдущем примере. Также здесь я в качестве источника укажу запрос, чтобы Вы видели, как можно использовать запросы в качестве источника.
--Удаление строки с ProductId = 4 --для того чтобы отработало условие WHEN NOT MATCHED DELETE dbo.TestTable WHERE ProductId = 4 --Запрос MERGE для синхронизации таблиц MERGE dbo.TestTable AS T_Base --Целевая таблица --Запрос в качестве источника USING (SELECT ProductId, ProductName, Summa FROM dbo. TestTableDop) AS T_Source (ProductId, ProductName, Summa) ON (T_Base.ProductId = T_Source.ProductId) --Условие объединения WHEN MATCHED THEN --Если истина (UPDATE) UPDATE SET ProductName = T_Source.ProductName, Summa = T_Source.Summa WHEN NOT MATCHED THEN --Если НЕ истина (INSERT) INSERT (ProductId, ProductName, Summa) VALUES (T_Source.ProductId, T_Source.ProductName, T_Source.Summa) --Удаляем строки, если их нет в TestTableDOP WHEN NOT MATCHED BY SOURCE THEN DELETE --Посмотрим, что мы сделали OUTPUT $action AS [Операция], Inserted.ProductId, Inserted.ProductName AS ProductNameNEW, Inserted.Summa AS SummaNEW,Deleted.ProductName AS ProductNameOLD, Deleted.Summa AS SummaOLD; --Не забываем про точку с запятой --Итоговый результат SELECT * FROM dbo. TestTable SELECT * FROM dbo.TestTableDop
В итоге мы видим, что у нас таблицы содержат одинаковые данные. Для этого мы выполнили две операции UPDATE, одну INSERT и одну DELETE. При этом мы использовали всего одну инструкцию MERGE.
Пример 3 – операция MERGE с дополнительным условием
Сейчас давайте выполним запрос похожий на запрос, который мы использовали в примере 1, только добавим дополнительное условие на обновление данных, например, мы будем обновлять TestTable только в том случае, если поле Summa, в TestTableDop, содержит какие-нибудь данные (например, мы не хотим использовать некорректные значения для обновления). Для того чтобы было видно, как отработало это условие, давайте предварительно очистим у одной строки в таблице TestTableDop поле Summa (поставим NULL).
--Очищаем поле сумма у одной строки в TestTableDop UPDATE dbo. TestTableDop SET Summa = NULL WHERE ProductId = 2 --Запрос MERGE MERGE dbo. TestTable AS T_Base --Целевая таблица USING dbo.TestTableDop AS T_Source --Таблица источник ON (T_Base.ProductId = T_Source.ProductId) --Условие объединения --Если истина + доп. условие отработало (UPDATE) WHEN MATCHED AND T_Source.Summa IS NOT NULL THEN UPDATE SET ProductName = T_Source.ProductName, Summa = T_Source.Summa WHEN NOT MATCHED THEN --Если НЕ истина (INSERT) INSERT (ProductId, ProductName, Summa) VALUES (T_Source.ProductId, T_Source.ProductName, T_Source.Summa) --Посмотрим, что мы сделали OUTPUT $action AS [Операция], Inserted.ProductId, Inserted.ProductName AS ProductNameNEW, Inserted.Summa AS SummaNEW, Deleted.ProductName AS ProductNameOLD, Deleted.Summa AS SummaOLD; --Не забываем про точку с запятой --Итоговый результат SELECT * FROM dbo. TestTable SELECT * FROM dbo.TestTableDop
В итоге у меня обновилось всего две строки, притом, что все три строки успешно выполнили условие объединения, но одна строка не обновилась, так как сработало дополнительное условие Summa IS NOT NULL, потому что поле Summa у строки с ProductId = 2, в таблице TestTableDop, не содержит никаких данных, т.е. NULL.
Заметка! Для комплексного изучения языка SQL и T-SQL рекомендую посмотреть мои видеокурсы по T-SQL, которые помогут Вам «с нуля» научиться работать с SQL и программировать на T-SQL в Microsoft SQL Server.
На этом у меня все, удачи!
sql — Предложение Oracle Merge Into Using?
Задавать вопрос
спросил
Изменено
3 года, 8 месяцев назад
Просмотрено
1к раз
Я не работаю с Oracle регулярно, но иногда меня завораживают возможности. Недавно я столкнулся с ситуацией, описанной ниже, и пытаюсь разобраться в этом.
Пытаясь следовать документации по оператору слияния из Справочника по языку SQL Oracle, я создал приведенный ниже оператор MERGE INTO. Он компилируется, но работает некорректно. Когда ON ( tbl.field_name = S.field_name ) оценивается как False , логика не перетекает в раздел (WHEN NOT MATCHED)
MERGE INTO table_name tbl ИСПОЛЬЗОВАНИЕ (ВЫБРАТЬ имя_поля ИЗ имя_таблицы, ГДЕ имя_поля = '12345') S ON (tbl.field_name = S.field_name) КОГДА СООТВЕТСТВУЕТ, ТО ОБНОВЛЯЕТСЯ. . . -- поток приходит сюда, когда ожидается, это работает корректно ЕСЛИ НЕ СООТВЕТСТВУЕТ, ВСТАВЬТЕ . . . -- Когда совпадение с (имя_поля) не существует, **поток сюда никогда не приходит?
Приведенный ниже оператор MERGE INTO работает правильно, но я не понимаю, почему он работает правильно. Сотрудник, который сейчас изолирован, помог мне с этим, а потом ушел без объяснений. Она изменила только пункты USING и ON. Я пытаюсь понять, как часть ( USING Dual ) заставляет это работать правильно? Или , почему предложение USING (в приведенном выше примере с явным SELECT) не работает должным образом? Может ли кто-нибудь помочь мне с этим?
MERGE INTO имя_таблицы tbl ИСПОЛЬЗОВАНИЕ двойного ВКЛ (tbl.field_name = '12345') КОГДА СООТВЕТСТВУЕТ, ТО ОБНОВЛЯЕТСЯ. . . -- поток приходит сюда, когда ожидается, это работает корректно ЕСЛИ НЕ СООТВЕТСТВУЕТ, ВСТАВЬТЕ . . . -- Если совпадение с (field_name) не существует, **поток поступает сюда корректно
- sql
- oracle
- plsql
Я думаю, что вы неправильно смотрите на сравнение между исходной и целевой таблицами.
Слияние первоначально основано на данных, которые находятся в исходной таблице, и , затем , есть ли соответствующие данные в целевой таблице. Вы, кажется, ожидаете, что это сработает наоборот.
С:
ИСПОЛЬЗОВАНИЕ (ВЫБРАТЬ имя_поля ИЗ имя_таблицы, ГДЕ имя_поля = '12345') S ON (tbl.field_name = S.field_name)
если в исходной таблице есть строка с этим значением, то S
имеет одну строку (при условии, что она уникальна), и в целевой таблице может быть или не быть совпадающая строка; он войдет либо в предложения matched, либо в not-matched, как и ожидалось, в зависимости от того, что находится в целевой таблице, но только с использованием значений из выбранной исходной строки.
Но если в исходной таблице нет строки с этим значением, тогда S
является пустым результирующим набором, поэтому предложение ON
ничего не делает, поэтому оно никогда не оценивается на самом деле — и в этом сценарии оно не t достигает несопоставленного предложения. Не с чем сравнивать, и «ничто» не соответствует или не соответствует чему-либо еще.
Принимая во внимание:
ПРИ ИСПОЛЬЗОВАНИИ двойного ВКЛ (tbl. field_name = '12345')
всегда ровно одна строка из dual
, поэтому предложение ON
всегда оценивается, хотя на самом деле оно не использует эту строку dual
или ее фиктивный столбец
, и в целевой таблице может быть или не быть совпадающая запись, поэтому переходит в ожидаемую ветвь. У вас не может быть пустого набора результатов из исходной таблицы, так как теперь это dual
, который не может быть пустым.
В любом случае кажется, что ваше несоответствующее предложение, по крайней мере, не использует данные из S
, что обычно имеет место — в противном случае двойная версия
тоже подойдет.
2
Когда ‘12345’ не найдено в table_name.field_name
, в первом случае вы используете таблицу без строк. Управление ДЕЙСТВИТЕЛЬНО переходит к , когда не соответствует, затем вставляет. .. ветвь
(не уверен, почему вы думаете, что это не так), но вставлять нечего, потому что S
пуст. Во втором примере, даже если это значение не найдено, вы с использованием таблицы dual
, которая имеет одну строку. Независимо от того, что находится в частях кода, которыми вы не поделились с нами, вы ДОЛЖНЫ ожидать различного поведения от двух разных операторов MERGE.
1
Зарегистрируйтесь или войдите в систему
Зарегистрируйтесь с помощью Google
Зарегистрироваться через Facebook
Зарегистрируйтесь, используя электронную почту и пароль
Опубликовать как гость
Электронная почта
Обязательно, но не отображается
Опубликовать как гость
Электронная почта
Требуется, но не отображается
MERGE в Postgres 15 и его сравнение с INSERT ON CONFLICT
Сегодня в 11-м эпизоде нашей серии мы рассмотрим команду MERGE
и ее отличия от команды INSERT ON CONFLICT
.
Поделитесь этим выпуском: Нажмите здесь, чтобы поделиться этим выпуском в Twitter и подпишитесь на наш канал YouTube.
СЛИЯНИЕ в Postgres 15
- Как работает команда MERGE в Postgres
- Почему в Postgres 9 есть команда INSERT ON CONFLICT0040
То, что мы обсуждали в этом выпуске 5 минут Postgres
Стенограмма
Начнем.
MERGE в Postgres 15
Ранее на этой неделе команда MERGE
была объединена с ветвью Postgres 15. MERGE
, для тех из вас, кто не знаком с этим, это стандартная команда SQL, которая позволяет вам брать определенные данные и объединять их с таблицей, а затем обновлять или вставка или удаление значений в этой таблице.
Другие базы данных, такие как SQL Server или Oracle, уже некоторое время имеют MERGE
, но несколько лет назад Postgres решила не добавлять MERGE
. Вместо этого он добавил альтернативную команду под названием INSERT ON CONFLICT
.
Теперь, сообщество потратило больше времени, и вы действительно увидите, что в новом патче, который был принят, было несколько авторов, и многие люди также просматривали его. Всегда есть риск, что эти вещи не попадут в финальную версию, но я думаю, что это лучший шанс, что MERGE
еще не попал в Postgres .
Как команда MERGE работает в Postgres
Давайте подробнее рассмотрим документацию по MERGE, которая уже доступна в ветке разработки, чтобы увидеть, как работает MERGE
.
- По сути, вы говорите
MERGE INTO
, а затем указываете имя таблицы.- Это стандартный синтаксис SQL, поэтому другие базы данных будут работать аналогично.
- Затем вы говорите
ИСПОЛЬЗОВАНИЕ
определенного источника данных.- Этот источник данных может быть другой таблицей или запросом. Например, запрос здесь может быть предложением
VALUES
, где у вас есть набор значений, которые вы пытаетесь вставить в таблицу, а затем вы пытаетесь решить, что делать, если значение уже существует. - Для каждой из этих входных строк вы указываете
join_condition
.join_condition
помогает сопоставить входные данные, источник данных, с целевой таблицей.
- Этот источник данных может быть другой таблицей или запросом. Например, запрос здесь может быть предложением
- Затем, в зависимости от того, существует ли совпадение с
join_condition
или нет, вы можете принять решение о выполнении определенных действий.- Вы можете сказать
WHEN MATCHED
, а затем какое-то другое условие, например, затем выполнитьUPDATE
, выполнитьDELETE
илиDOTHING
. Аналогично,КОГДА НЕ СООТВЕТСТВУЕТ
, вы также можете выбратьВСТАВИТЬ
данные, которые часто будут использоваться, илиНИЧЕГО НЕ ДЕЛАТЬ
.
- Вы можете сказать
Довольно универсальный синтаксис здесь, и: это стандартные команды INSERT
и UPDATE
, которые вы можете использовать. Я бы сказал, что есть много вариантов использования, которые я вижу для этого . Самый простой вариант использования, конечно, если есть существующие данные, вы можете просто убедиться, что вы INSERT
или UPDATE
. Еще одна вещь, которую вы можете сделать с этим, — вы также можете использовать его, например, для обновления определенного баланса. Пример в вышеупомянутых документах: есть таблица учетных записей клиентов, у вас есть таблица последних транзакций, а затем вы обновляете баланс учетной записи по мере обработки этих данных. Затем вы говорите, когда это соответствует: вы увеличиваете баланс. Когда это не соответствует: вы вставляете новую строку в таблицу учетных записей клиентов с этой транзакцией в качестве начального значения.
Существуют разные способы написания этих запросов, но в целом это очень полезный синтаксис. Я очень надеюсь, что это войдет в финальную версию.
Почему в Postgres есть команда INSERT ON CONFLICT? Postgres 9.
5 добавил другой синтаксис под названием INSERT ON CONFLICT
. В документации MERGE
вы можете увидеть, где написано:
Вы также можете рассмотреть возможность использования
INSERT ON CONFLICT
в качестве альтернативного оператора, который предлагает возможность запускаUPDATE
, если происходит параллельнаяINSERT
. Существуют различия и ограничения между этими двумя типами операторов, и они не являются взаимозаменяемыми.
Я думаю, очень важно знать, что есть компромиссы для обоих из них, и вы можете использовать INSERT ON CONFLICT
, когда вы не хотите использовать ОБЪЕДИНЕНИЕ
.
Вам может быть интересно, что это за ситуации. Питер Геохеган, который был первоначальным автором функции INSERT ON CONFLICT
, на самом деле сделал очень полезный комментарий здесь, в Твиттере, когда люди говорили об этом.
Комментарий, который он, по сути, сделал, заключается в том, что недостатком обработки параллелизма MERGE
является то, что когда вы одновременно INSERT
, то есть в то же время, когда вы выполняете оператор MERGE
, есть еще INSERT
происходит, то MERGE
может этого не заметить. MERGE
войдет в свою логику INSERT
, а затем получит уникальное нарушение.
Я вспоминаю, что когда он изначально разрабатывал функцию INSERT ON CONFLICT
, из-за этого ограничения того, как MVCC работает в Postgres, вы не можете реализовать MERGE
с его общим синтаксисом и параметрами для работы в одном и том же надежном способ . Если вы хотите универсальность MERGE
, вы должны принять тот факт, что вы можете получить уникальные нарушения ограничений, когда есть одновременные вставки, по сравнению с INSERT ON CONFLICT
, способ, которым он разработан с его спекулятивными вставками, гарантирует, что вы либо получите INSERT
или UPDATE
, и это верно, даже если есть одновременные вставки. Вы можете выбрать INSERT ON CONFLICT
, если вам нужна гарантия.
Большое спасибо за внимание. Это были 5 минут Postgres, подпишитесь на наш канал на YouTube и следите за нами в Twitter, чтобы узнавать о новых эпизодах.