Delete merge oracle: BASE — MERGE Statement Enhancements in Oracle Database 10g

Сообщение об ошибке 8672 — оператор MERGE пытался обновить или удалить одну и ту же строку более одного раза

12 марта 2017 г., 20:30:13

Пинал Дэйв

Хотя я давно веду блог о SQL Server, я все еще считаю, что есть еще много ошибок, которые я не обнаружил. Всегда интересно увидеть новую ошибку и найти решение проблемы. Давайте посмотрим, как исправить ошибку, связанную с оператором MERGE.

Вот одна из ошибок, с которыми я столкнулся при подготовке к демонстрации.

Сообщение 8672, уровень 16, состояние 1, строка 19

Оператор MERGE попытался выполнить ОБНОВЛЕНИЕ или УДАЛЕНИЕ одной и той же строки более одного раза. Это происходит, когда целевая строка соответствует более чем одной исходной строке. Оператор MERGE не может ОБНОВИТЬ/УДАЛИТЬ одну и ту же строку целевой таблицы несколько раз. Уточните предложение ON, чтобы целевая строка соответствовала не более чем одной исходной строке, или используйте предложение GROUP BY, чтобы сгруппировать исходные строки.

Пока сообщение об ошибке сообщало мне о проблеме, я хотел узнать, как ее избежать. Вот пример кода, который любой может использовать и воспроизвести ту же ошибку.

 SET NOCOUNT ON 
GO
USE tempdb
GO
CREATE TABLE Employee(EmpID INTEGER,EmpName VARCHAR(15))
GO
INSERT INTO Employee VALUES(1,'Pinal')
INS ERT INTO Employee VALUES(2,'SQLServer ')
INSERT INTO Employee VALUES(1,'SQLAuthority')
GO
CREATE TABLE EmployeeSalary (EmpID INTEGER ,Salary INTEGER)
GO
INSERT INTO EmployeeSalary VALUES(1,235)
INSERT INTO EmployeeSalary VALUES(2,255)
GO
MERGE EmployeeSalary AS es
USING (SELECT EmpID,EmpName FROM Employee) AS m
ON es.EmpID = m. EmpID
КОГДА СООТВЕТСТВУЕТ ТО
обновление SET es.Salary = es.Salary + 25;

Глядя на сообщение об ошибке, становится ясно, что оператор слияния пытается обновить целевую таблицу «Оклад сотрудников», но при этом SQL-сервер обнаружил повторяющуюся запись в исходной таблице (определяемой как запрос)

Следовательно, здесь, в таблице Employee, которая является исходной таблицей в операторе слияния, есть две похожие записи для EmpID (1) . Это пытается обновить целевую таблицу Employee Salary, которая имеет одну уникальную запись для этого EmpID. Следовательно, эта операция не разрешена в слиянии, и она выдает указанную выше ошибку, когда в исходной таблице наблюдается повторяющаяся запись (ссылка на столбец в предложении ON в слиянии).

 

Чтобы решить эту проблему, нам необходимо удалить повторяющиеся данные из исходных объектов или предотвратить возникновение таких ошибок. Мы также можем создать ограничения первичного ключа для полей, указанных в предложении ON оператора слияния.

Ссылка: Pinal Dave (http://blog.SQLAuthority.com)  

Теги:

SQL-сервер

Автор: Пинал Дэйв

Пинал Дэйв — специалист по технологиям Microsoft (база данных и бизнес-аналитика). Он написал более 1700 статей на эту тему в своем блоге по адресу http://blog.sqlauthority.com. Он динамичный и опытный главный архитектор базы данных, специализирующийся на настройке производительности SQL Server и имеющий более 7 лет практического опыта. Он имеет степень магистра наук и ряд сертификатов, включая MCTS, MCDBA и MCAD (.NET). Он также является региональным наставником PASS Asia. До прихода в Microsoft он был награжден наградой Microsoft MVP в течение трех лет подряд за свой вклад в сообщество.

удаление дорогостоящего «слияния и декартова соединения»

 

 

 

Советы по Oracle Database от Дональда Берлесона

Вопрос:
У меня есть этот SQL, который выполняет «декартово соединение слиянием», и он
вечно бежать. Его
потребляет 60% ресурсов базы данных, и мне сказали, что
декартово соединение слиянием — плохой план выполнения.

ВЫБЕРИТЕ ОТЛИЧНЫЙ A.CUSTOMER_REF,
ATTRIBUTE_VALUE
ОТ
G42PRODUCTATTRIBUTE E,
G42CUSTHASPACKAGE A,
G42CUSTHASPRODUCT C,
G42CUSTPRODUCTDETAILS B,
G42CUSTPRODUCTATTRDETAILS D
ГДЕ 9 0012 A. CUSTOMER_REF = :B2
AND
B.ACCOUNT_NUM =:B1
AND
A.CUSTOMER_REF = B.CUSTOMER_REF
AND
B.CUSTOMER_REF = C.CUSTOMER_REF
AND
A.PACKAGE_SEQ = C.PACKAGE_SEQ
AND
B.PRODUCT_SEQ = C.PRODUCT_SEQ
AND
A.CUSTOMER_REF = D.CUSTOMER_REF
AND
C.PRODUCT_SEQ = D.PRODUCT_SEQ
AND
D.PRODUCT_ID+0 = 1
AND
D.PRODUCT_ATTRIBUTE_SUBID = E.PRODUCT _AT TRIBUTE_SUBID И
D.PRODUCT_ID+0 = E .PRODUCT_ID
AND
E.ATTRIBUTE_UA_NAME = ‘CUST_ORD_NUMBER’
AND
A.PACKAGE_ID
IN (1, 14, 15, 16, 19, 22, 23, 24, 26, 37)

PLAN_TABLE_OUTPUT
———————————————— —————————
| Идентификатор | Операция | Имя | Ряды | Байты | Стоимость |
————————————————— —————————————————
| 0 | ВЫБЕРИТЕ ЗАЯВЛЕНИЕ | | 1 | 103 | 2068 |
| 1 | СОРТИРОВАТЬ УНИКАЛЬНО | | 1 | 103 | 2068 |
| 2 | ДОСТУП К ТАБЛИЦАМ ПО INDEX ROWID | G42CUSTPRODUCTATTRДЕТАЛИ |
1 | 27 | 1
| 3 | ВЛОЖЕННЫЕ ЦИКЛЫ | | 1 | 103 | 2067 |
| 4 | ВЛОЖЕННЫЕ ЦИКЛЫ | | 1 | 76 | 2066 |
| 5 | ВЛОЖЕННЫЕ ЦИКЛЫ | | 4 | 236 | 2065 |
| 6 | ОБЪЕДИНЯЙТЕ ДЕКОРТОВУЮ СЕНСОРНУЮ | | 4 | 148 | 2064 |
| 7 | ДОСТУП К ТАБЛИЦАМ ПО ИНДЕКСУ ROWID| G42ХАРАКТЕРИСТИКИ ПРОДУКТА | 2 | 42
| 1 |
| 8 | ИНДЕКС ДИАПАЗОН СКАН | G42PRODUCTATTRIBUTE_AK2 | 6 | | 1 |
| 9 | БУФЕРНАЯ СОРТИРОВКА | | 2 | 32 | 2063 |
| 10 | ИНДЕКС ПОЛНОЕ СКАНИРОВАНИЕ | G42CUSHASPKG_CUSREF_PKSQ_PKID | 2 | 32
| 6875 |
| 11 | ДОСТУП К ТАБЛИЦАМ ПО INDEX ROWID | G42CUSTДЕТАЛИ ПРОДУКТА | 1 |
22 | 1 |
| 12 | ИНДЕКС ДИАПАЗОН СКАН | G42CUSTPRODUCTDETAILS_AK3 | 1 | | 1 |
| 13 | ДОСТУП К ТАБЛИЦАМ ПО INDEX ROWID | G42CUSTHASПРОДУКТ | 1 | 17
| 1 |
| 14 | ИНДЕКС ДИАПАЗОН СКАН | G42CUSTHASPRODUCT_PK1 | 1 | | 0 |
| 15 | ИНДЕКС ДИАПАЗОН СКАН | G42CUSTPRODUCTATTRDETAILS_PK1 | 1 | |
1 |
 

Как удалить соединение слиянием
картезианский?

Ответ:
Есть несколько причин, по которым ваш SQL будет выполнять декартово соединение слиянием. декартовский
Объединения слиянием также могут быть вызваны:

— Забыли добавить условие объединения таблиц в предложение WHERE
— Отсутствующие индексы соединения
— Статистика плохой/устаревшей схемы (повторно проанализировать с помощью dbms_stats )

У тебя
4-way table join, и я бы начал с использования

Подсказка ORDERED для принудительного выбора оптимального порядка соединения.

Что касается декартового соединения слиянием, сначала внимательно проверьте ГДЕ
пункт, чтобы убедиться, что вы предоставили правильное соединение
условия (например, , где a.primary_key= b.foreign_key ).

Дополнительная информация об отключении декартовых объединений слиянием, если
желательно, есть в наличии

ЗДЕСЬ.

Получить полную версию
Информация о настройке Oracle SQL


Знаковая книга
«Продвинутый Оракул
SQL Tuning  Полное руководство» 
наполнен ценной информацией о настройке Oracle SQL.

Imacros | Все права защищены © 2021