As someone explained earlier, probably your MERGE statement tries to update the same row more than once and that does not work (could cause ambiguity).
Here is one simple example. MERGE that tries to mark some products as found when matching the given search patterns:
CREATE TABLE patterns(search_pattern VARCHAR2(20));
INSERT INTO patterns(search_pattern) VALUES('Basic%');
INSERT INTO patterns(search_pattern) VALUES('%thing');
CREATE TABLE products (id NUMBER,name VARCHAR2(20),found NUMBER);
INSERT INTO products(id,name,found) VALUES(1,'Basic instinct',0);
INSERT INTO products(id,name,found) VALUES(2,'Basic thing',0);
INSERT INTO products(id,name,found) VALUES(3,'Super thing',0);
INSERT INTO products(id,name,found) VALUES(4,'Hyper instinct',0);
MERGE INTO products p USING
(
SELECT search_pattern FROM patterns
) o
ON (p.name LIKE o.search_pattern)
WHEN MATCHED THEN UPDATE SET p.found=1;
SELECT * FROM products;
If patterns
table contains Basic%
and Super%
patterns then MERGE works and first three products will be updated (found). But if patterns
table contains Basic%
and %thing
search patterns, then MERGE does NOT work because it will try to update second product twice and this causes the problem. MERGE does not work if some records should be updated more than once. Probably you ask why not update twice!?
Here first update 1 and second update 1 are the same value but only by accident. Now look at this scenario:
CREATE TABLE patterns(code CHAR(1),search_pattern VARCHAR2(20));
INSERT INTO patterns(code,search_pattern) VALUES('B','Basic%');
INSERT INTO patterns(code,search_pattern) VALUES('T','%thing');
CREATE TABLE products (id NUMBER,name VARCHAR2(20),found CHAR(1));
INSERT INTO products(id,name,found) VALUES(1,'Basic instinct',NULL);
INSERT INTO products(id,name,found) VALUES(2,'Basic thing',NULL);
INSERT INTO products(id,name,found) VALUES(3,'Super thing',NULL);
INSERT INTO products(id,name,found) VALUES(4,'Hyper instinct',NULL);
MERGE INTO products p USING
(
SELECT code,search_pattern FROM patterns
) s
ON (p.name LIKE s.search_pattern)
WHEN MATCHED THEN UPDATE SET p.found=s.code;
SELECT * FROM products;
Now first product name matches Basic%
pattern and it will be updated with code B
but second product matched both patterns and cannot be updated with both codes B
and T
in the same time (ambiguity)!
That’s why DB engine complaints. Don’t blame it! It knows what it is doing!
#oracle #plsql
Вопрос:
Я получаю
ORA-30926: не удается получить стабильный набор строк в исходных таблицах
в следующем запросе:
MERGE INTO table_1 a USING (SELECT a.ROWID row_id, 'Y' FROM table_1 a ,table_2 b ,table_3 c WHERE a.mbr = c.mbr AND b.head = c.head AND b.type_of_action lt;gt; '6') src ON ( a.ROWID = src.row_id ) WHEN MATCHED THEN UPDATE SET in_correct = 'Y';
Я запустил table_1
приложение с данными, а также запустил внутренний запрос ( src
), который также содержит данные.
Почему возникла эта ошибка и как ее можно устранить?
Ответ №1:
Обычно это вызвано дубликатами в запросе, указанном в предложении USING. Это, вероятно, означает, что TABLE_A является родительской таблицей, и один и тот же идентификатор строки возвращается несколько раз.
Вы могли бы быстро решить проблему, используя в своем запросе значение DISTINCT (на самом деле, если » Y » является постоянным значением, вам даже не нужно указывать его в запросе).
Предполагая, что ваш запрос верен (не знаю ваших таблиц), вы могли бы сделать что-то вроде этого:
MERGE INTO table_1 a USING (SELECT distinct ta.ROWID row_id FROM table_1 a ,table_2 b ,table_3 c WHERE a.mbr = c.mbr AND b.head = c.head AND b.type_of_action lt;gt; '6') src ON ( a.ROWID = src.row_id ) WHEN MATCHED THEN UPDATE SET in_correct = 'Y';
Комментарии:
1. Вероятно, поэтому другие подходы (для меня) также возвращали мне другие ошибки (например, «процедура, функция, пакет или тип здесь не разрешены» и «Невозможно изменить столбец, который сопоставляется с ошибкой таблицы, не сохраненной ключом, при попытке вставить в представление»). ~ Если это поможет кому-то еще, я получил ту же ошибку даже после добавления distinct, пока я не перестроил соединения моего внутреннего запроса, поэтому я начал с таблицы, в которой возвращалось более одной строки, и внутреннее соединение оттуда… если это имеет смысл.
Ответ №2:
Вероятно, вы пытаетесь обновить одну и ту же строку целевой таблицы несколько раз. Я только что столкнулся с той же проблемой в заявлении о слиянии, которое я разработал. Убедитесь, что ваше обновление не касается одной и той же записи более одного раза при выполнении слияния.
Комментарии:
1. 1, спасибо, это только что произошло со мной в целевой таблице с небольшим количеством дубликатов (по крайней мере, на основе ключей, используемых при слиянии).
Ответ №3:
Как устранить ошибки ORA-30926? (Идентификатор документа 471956.1)
1) Определите ошибочное утверждение
изменить события набора сеансов «30926 имя трассировки ошибка 3-го уровня»;
или
изменить системные события набора «30926 ошибка имени трассировки отключена»;
и следите за файлами .trc в UDUMP, когда это произойдет.
2) Найдя инструкцию SQL, проверьте ее правильность (возможно, используя explain plan или tkprof для проверки плана выполнения запроса) и проанализируйте или вычислите статистику по соответствующим таблицам, если это не было сделано в последнее время. Перестройка (или удаление/воссоздание) индексов также может помочь.
3.1) Является ли оператор SQL СЛИЯНИЕМ? оцените данные, возвращаемые предложением USING, чтобы убедиться, что в соединении нет повторяющихся значений. Измените инструкцию merge, чтобы включить детерминированное предложение where
3.2) Является ли это заявлением об ОБНОВЛЕНИИ с помощью представления? Если это так, попробуйте заполнить результат представления в таблицу и попробуйте обновить таблицу напрямую.
3.3) Есть ли на столе триггер? Попробуйте отключить его, чтобы посмотреть, не сработает ли он по-прежнему.
3.4) Содержит ли оператор не подлежащее слиянию представление в подзапросе «В»? Это может привести к возвращению повторяющихся строк, если в запросе есть предложение «ДЛЯ ОБНОВЛЕНИЯ». См. Ошибку 2681037
3.5) Есть ли в таблице неиспользуемые столбцы? Их удаление может предотвратить ошибку.
4) Если изменение SQL не устраняет ошибку, проблема может быть связана с таблицей, особенно если есть связанные строки. 4.1) Запустите инструкцию «ПРОАНАЛИЗИРОВАТЬ КАСКАД ПРОВЕРКИ СТРУКТУРЫ ТАБЛИЦЫ» для всех таблиц, используемых в SQL, чтобы проверить, нет ли каких-либо повреждений в таблице или ее индексах. 4.2) Проверьте и удалите все СВЯЗАННЫЕ или перенесенные СТРОКИ в таблице. Есть способы свести это к минимуму, например, правильная настройка PCTFREE. Используйте Примечание 122020.1 — Цепочка строк и миграция 4.3) Если таблица дополнительно организована по индексам, см.: Примечание 102932.1 — Мониторинг цепочек строк в IOTs
Ответ №4:
Сегодня произошла ошибка на 12c, и ни один из существующих ответов не подходит (никаких дубликатов, никаких недетерминированных выражений в предложении WHERE). Мой случай был связан с другой возможной причиной ошибки, согласно тексту сообщения Oracle (выделено ниже).:
ORA-30926: не удалось получить стабильный набор строк в исходных таблицах
Причина: Не удалось получить стабильный набор строк из-за большой активности dml или недетерминированного предложения where.
Слияние было частью более крупного пакета и выполнялось в оперативной базе данных со многими одновременными пользователями. Не было никакой необходимости менять заявление. Я просто зафиксировал транзакцию перед слиянием, затем выполнил слияние отдельно и зафиксировал снова. Таким образом, решение было найдено в предлагаемом действии сообщения:
Действие: Удалите все недетерминированные предложения where и переиздайте dml.
Комментарии:
1. Я получал это сообщение об ошибке при импорте данных по сети (с использованием
NETWORK_LINK
параметра, который напрямую подключается к исходной базе данных) на этапе сбора статистики, и ваша выделенная заметка, вероятно, объясняет это. К счастью, пострадала только статистика.
Ответ №5:
Дальнейшее разъяснение использования DISTINCT для устранения ошибки ORA-30926 в общем случае:
Вам необходимо убедиться, что набор данных, указанный в предложении USING (), не содержит повторяющихся значений столбцов объединения, т. е. столбцов в предложении ON ().
В примере OP, где предложение USING выбирает только ключ, было достаточно добавить DISTINCT в предложение USING. Однако в общем случае предложение USING может выбрать комбинацию ключевых столбцов для сопоставления и столбцов атрибутов, которые будут использоваться в ОБНОВЛЕНИИ … Оговорка О НАБОРЕ. Поэтому в общем случае добавление DISTINCT в предложение USING все равно позволит обновлять разные строки для одних и тех же ключей, и в этом случае вы все равно получите ошибку ORA-30926.
Это разработка ответа DCookie и пункта 3.1 в ответе Тагара, который, по моему опыту, может быть не сразу очевиден.
Комментарии:
1. Я не понимаю, почему голосуют против. Это был мой случай (многоколоночные), и четкий обходной путь не возымел никакого эффекта. Итак, как говорит @Durban_legend, нужно убедиться, что нет ошибок (я удалил некоторые столбцы идентификаторов «остатки»), а затем использовать Distinct и работать. Отклоняю это уточнение, поскольку оно не было сразу очевидно в принятом ответе.
Ответ №6:
SQL Error: ORA-30926: unable to get a stable set of rows in the source tables 30926. 00000 - "unable to get a stable set of rows in the source tables" *Cause: A stable set of rows could not be got because of large dml activity or a non-deterministic where clause. *Action: Remove any non-deterministic where clauses and reissue the dml.
Эта ошибка произошла у меня из-за повторяющихся записей(16K)
Я попробовал с уникальным, это сработало .
но опять же, когда я попытался объединить без уникальных, та же проблема возникла во второй раз, когда это было связано с фиксацией
после слияния, если фиксация не будет выполнена, будет показана та же ошибка.
Без unique запрос будет работать, если фиксация задается после каждой операции слияния.
Ответ №7:
Я не смог решить эту проблему через несколько часов. В конце концов я просто сделал выбор из двух соединенных таблиц, создал выписку и создал отдельные инструкции SQL update для 500 строк в таблице. Некрасиво, но лучше потратить часы, пытаясь заставить запрос работать.
I recently encountered a Strange issue on Merge statement. It failed with ORA 30926 error.
I have already checked for the below pitfalls,
- Duplicate records check in Source and Target table – Came out clean
- Source and Target tables Analyze structure – Came out clean
- Source and Target tables Indexes Analyze structure – Came out clean
- Same Merge SQL when DBA tried in SYS user – Worked. Still Puzzling
- Same Merge SQL runs successfully in Copy table of Target – Worked. Still Puzzling
- DBA Bounced the TEST server. Though not convincing wanted to give a try as the issue appears to be strange – Didn’t Workout
- Gathered the statistics
- Truncate the Original target table and reload from Copy table and try the Merge again — Didn’t Workout. Failed with same error
Nutshell Script:
MERGE INTO TGT_SCHEMA.EMP T
USING SRC_SCHEMA.S_EMP S
ON
(
T.EMPLOYEE_NO = S.EMPLOYEE_NO AND
T.START_DATE = S.START_DATE
)
Unique Index (EMPLOYEE_NO, START_DATE
) exists on Target table and a normal Index of same combination exists on Source table. Target table is a partitioned table and there are some VPD policies applied to other columns.
My Database version : Oracle 11.2.0.3.0
asked Mar 18, 2016 at 13:21
1
If you really checked everything you said correctly, then this is a bit of a puzzler. I think #4 in your diagnostic checklist may be telling: that the same statement worked when executed as SYS.
For fun, check to see where there are any VPD policies on either table (DBMS_RLS
package). If there are, try to disable them and retry the merge.
answered Mar 18, 2016 at 13:33
Matthew McPeakMatthew McPeak
17.6k2 gold badges26 silver badges59 bronze badges
This error happens on MERGE when the USING clause returns more than one row for one or more target rows according to your matching criteria. Since it can’t know which of two updates to do first, it gives up.
Run:
SELECT matching_column1, ..matching_ColumnN, count(*)
FROM (
<your USING query>
)
group by matching_column1, ..matching_ColumnN
having count(*) > 1
To find the offending source data. At that point either modify your USING query to resolve it, change your matching criteria, or clean up bad data — whichever is appropriate.
EDIT — Add another item:
One other possibility — you will get this error if you try to update a column in your target that is referenced in your ON clause.
So make sure that you are not trying to UPDATE the EMPLOYEE_NO or START_DATE fields.
answered Mar 18, 2016 at 13:29
2
If you’ve ever used MERGE, then it is quite probable that you are familiar with ORA-30926 – unable to get a stable set of rows in the source tables. You have also probably noticed, that in case of hitting this error, your query takes longer. Three times longer, because the whole query is executed three times, as following tests show.
I already wrote about key-preserved tables and hitting the ORA-30926 or ORA-01779 in my post about BYPASS_UJVC hint.
There are several possible reasons for this error. The most common is probably following.
According to the documentation, Merge is a deterministic statement. It means you cannot update the same row of the target table multiple times in the same MERGE statement. If a table or a query in USING clause has duplicates with regard to the keys used in ON clause, and those records will match, thus are going to be updated multiple times, then you’ll get the ORA-30926 – unable to get a stable set of rows in the source tables. Let’s show this on the following test case:
CREATE TABLE t_source (id NUMBER, val NUMBER); CREATE TABLE t_target (id NUMBER, val NUMBER); INSERT INTO t_source VALUES (1,10); INSERT INTO t_source VALUES (2,10); INSERT INTO t_source VALUES (3,10); INSERT INTO t_target VALUES (1,1); INSERT INTO t_target VALUES (2,1); COMMIT;
Now, we execute a MERGE statement, merging records from T_SOURCE into T_TARGET. We await no difficulties here, because ID in T_SOURCE is unique.
ALTER SESSION SET STATISTICS_LEVEL = ALL; COLUMN SQL_ID NEW_VAL SQL_ID SET PAGESIZE 0 SET LINESIZE 300 -- First Merge without an error MERGE /*+ gather_plan_statistics */ /* MERGE_TEST_1 */ INTO t_target t USING t_source q ON (q.id = t.id) WHEN MATCHED THEN UPDATE SET t.val = t.val + q.val WHEN NOT MATCHED THEN INSERT (id, val) VALUES(q.id, q.val); ROLLBACK; SELECT sql_id from v$sql vs WHERE VS.SQL_TEXT LIKE '%MERGE_TEST_1%' AND VS.SQL_TEXT NOT LIKE '%v$sql%'; SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(sql_id=>'&sql_id', format=>'IOSTATS LAST')); ... Plan hash value: 445881280 ------------------------------------------------------------------------------------------- | Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | ------------------------------------------------------------------------------------------- | 0 | MERGE STATEMENT | | 1 | | 0 |00:00:00.01 | 22 | | 1 | MERGE | T_TARGET | 1 | | 0 |00:00:00.01 | 22 | | 2 | VIEW | | 1 | | 3 |00:00:00.01 | 14 | |* 3 | HASH JOIN OUTER | | 1 | 3 | 3 |00:00:00.01 | 14 | | 4 | TABLE ACCESS FULL| T_SOURCE | 1 | 3 | 3 |00:00:00.01 | 7 | | 5 | TABLE ACCESS FULL| T_TARGET | 1 | 2 | 2 |00:00:00.01 | 7 | -------------------------------------------------------------------------------------------
Note that all steps of this execution plan were executed only once (Starts=1). Actual rows are also feasible: join three rows in T_SOURCE with two rows in T_TARGET.
Now we’ll create a duplicate row in T_SOURCE and repeat our exercise:
-- Now creating duplicate record in the source table which leads to ORA-30926 INSERT INTO t_source (id, val) VALUES (2,20); COMMIT; MERGE /*+ gather_plan_statistics */ /* MERGE_TEST_2 */ INTO t_target t USING t_source q ON (q.id = t.id) WHEN MATCHED THEN UPDATE SET t.val = t.val + q.val WHEN NOT MATCHED THEN INSERT (id, val) VALUES(q.id, q.val); SELECT sql_id from v$sql vs WHERE VS.SQL_TEXT LIKE '%MERGE_TEST_2%' AND VS.SQL_TEXT NOT LIKE '%v$sql%'; SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(sql_id=>'&sql_id', format=>'IOSTATS LAST')); Plan hash value: 445881280 ------------------------------------------------------------------------------------------- | Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | ------------------------------------------------------------------------------------------- | 0 | MERGE STATEMENT | | 3 | | 0 |00:00:00.01 | 36 | | 1 | MERGE | T_TARGET | 3 | | 0 |00:00:00.01 | 36 | | 2 | VIEW | | 3 | | 10 |00:00:00.01 | 40 | |* 3 | HASH JOIN OUTER | | 3 | 4 | 10 |00:00:00.01 | 40 | | 4 | TABLE ACCESS FULL| T_SOURCE | 3 | 4 | 12 |00:00:00.01 | 21 | | 5 | TABLE ACCESS FULL| T_TARGET | 3 | 2 | 6 |00:00:00.01 | 19 | -------------------------------------------------------------------------------------------
What’s going on here? Note, how all steps being executed three times (starts=3). A-Rows for T_TARGET is six (2 rows x 3 times) and for T_SOURCE is now 12 (now 4 rows x 3 times).
Is this a flaw of display_cursor or is Oracle in fact doing all the stuff three times?
Maybe we can prove it, creating some triggers:
SET SERVEROUTPUT ON CREATE OR REPLACE TRIGGER t_merge_test BEFORE INSERT OR UPDATE ON t_target FOR EACH ROW BEGIN IF INSERTING THEN DBMS_OUTPUT.PUT_LINE('Inserting ID='||:new.id||' new val='||:new.val); ELSIF UPDATING THEN DBMS_OUTPUT.PUT_LINE('Updating ID='||:new.id||' new val='||:new.val||', old val='||:old.val); END IF; END; / CREATE OR REPLACE FUNCTION test_func (id NUMBER, val NUMBER) RETURN NUMBER IS BEGIN DBMS_OUTPUT.PUT_LINE('Querying ID '||id||' val '||val); RETURN val; END; / MERGE /*+ gather_plan_statistics */ /* MERGE_TEST_3 */ INTO t_target t USING (SELECT id, test_func(id, val) val FROM t_source) q ON (q.id = t.id) WHEN MATCHED THEN UPDATE SET t.val = t.val + q.val WHEN NOT MATCHED THEN INSERT (id, val) VALUES(q.id, q.val); Querying ID 1 val 10 Updating ID=1 new val=11, old val=1 Querying ID 2 val 20 Updating ID=2 new val=21, old val=1 Querying ID 2 val 10 Updating ID=2 new val=11, old val=1 Querying ID 2 val 10 Querying ID 1 val 10 Querying ID 2 val 20 Querying ID 2 val 10 Querying ID 3 val 10 Querying ID 1 val 10 Updating ID=1 new val=11, old val=1 Querying ID 2 val 20 Updating ID=2 new val=21, old val=1 Querying ID 2 val 10 Updating ID=2 new val=11, old val=1 SELECT DISTINCT FIRST_VALUE(sql_id) OVER (ORDER BY VS.LAST_ACTIVE_TIME DESC) sql_id FROM v$sql vs WHERE VS.SQL_TEXT LIKE '%MERGE_TEST_3%' AND VS.SQL_TEXT NOT LIKE '%v$sql%'; SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(sql_id=>'&sql_id', format=>'IOSTATS LAST')); ---------------------------------------------------------------------------------------------------- | Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads | ---------------------------------------------------------------------------------------------------- | 0 | MERGE STATEMENT | | 3 | | 0 |00:00:00.07 | 645 | 11 | | 1 | MERGE | T_TARGET | 3 | | 0 |00:00:00.07 | 645 | 11 | | 2 | VIEW | | 3 | | 10 |00:00:00.07 | 646 | 11 | |* 3 | HASH JOIN OUTER | | 3 | 4 | 10 |00:00:00.01 | 40 | 0 | | 4 | TABLE ACCESS FULL| T_SOURCE | 3 | 4 | 12 |00:00:00.01 | 21 | 0 | | 5 | TABLE ACCESS FULL| T_TARGET | 3 | 2 | 6 |00:00:00.01 | 19 | 0 | ----------------------------------------------------------------------------------------------------
From the output of our function and trigger one could clearly see, that we were actually querying and updating until we found a row which would be updated twice, then re-querying all rows, then start updating again and finally throwing an error. Last year I’ve had an opportunity to ask Jonathan Lewis at the CBO Days 2014 in Zurich, an event organized by Trivadis, the company I work for. Of course, his answer showed me the right direction to think. We are dealing with statement restarts here. In this case it is even possible with only one session. I’ll show this in my next post.
There are also a couple of bugs related to ORA-30926, see MOS How to Troubleshoot ORA-30926 Errors? (Doc ID 471956.1)
Related Posts
I was on call last week and I got a ticket about a batch job that was failing on a MERGE statement with an ORA-30926 error. Our support team worked around it by deleting some duplicate rows in a table that was feeding into the MERGE. This week I wanted to go back and try to understand what would cause ORA-30926 errors on MERGE statements.
I read through some blog posts and Oracle support documents relating to ORA-30926 and merge. Then I tried building some simple test scripts to see when you get ORA-30926 on a MERGE. At the end of my search I came back to this simple statement from the 18c SQL Language Reference manual’s description of the MERGE statement:
MERGE is a deterministic statement. You cannot update the same row of the target table multiple times in the same MERGE statement.
I was puzzled by the term “deterministic” but “cannot update the same row…multiple times” seems simple enough. I created test scripts to show whether you can update the same row multiple times with a MERGE: zip
Here are the two test tables:
create table target (a number,b number);
create table source (a number,b number);
Here is data and a MERGE statement that causes the error:
SQL> insert into target values (1,1);
SQL> insert into source values (1,2);
SQL> insert into source values (1,3);
SQL> merge into target
2 using source
3 on (target.a = source.a)
4 when matched then
5 update set target.b=source.b;
using source
*
ERROR at line 2:
ORA-30926: unable to get a stable set of rows in the source tables
This seems very simple. We join the source and target tables on column A with value 1. The merge statement tries to update column B on the target table row twice. It tries to set it to 2 and then to 3. I guess this is where the term “deterministic” comes in. If the merge statement updated B to 2 and 3 which would it do first and which second?
The example above with values 2 and 3 for B makes good sense but I saw some odd behavior when I used source rows with 1 and 2 for the B values of the two rows. With B values of 1 and 2 in this case the MERGE does not get an error:
SQL> insert into target values (1,1);
SQL> insert into source values (1,1);
SQL> insert into source values (1,2);
SQL> merge into target
2 using source
3 on (target.a = source.a)
4 when matched then
5 update set target.b=source.b;
2 rows merged.
SQL> select * from target;
A B
---------- ----------
1 2
This seems to contradict the idea that you cannot update the same row multiple times with a MERGE. In this case it seems like B is updated twice, once to 1 which is what it already was set to and then to 2. I guess this works because B was already set to 1 so the update of B to the same value does not count as an update. It seems like only one update took place and then B ends up set to 2.
This example does not work with a slightly different MERGE statement on Oracle 12.1 or earlier:
SQL> select banner from v$version;
BANNER
--------------------------------------------------------------------------------
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
SQL> merge into target
2 using source
3 on (target.a = source.a)
4 when matched then
5 update set target.b=source.b
6 when not matched then
7 insert values (source.a,source.b);
using source
*
ERROR at line 2:
ORA-30926: unable to get a stable set of rows in the source tables
SQL> select * from source;
A B
---------- ----------
1 1
1 2
SQL>
SQL> select * from target;
A B
---------- ----------
1 1
All that I can say based on these two tests is that sometimes an update of a column to the same value counts as an update and sometimes it does not. The preceding example works on 12.2:
SQL> select banner from v$version;
BANNER
--------------------------------------------------------------------------------
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
SQL> merge into target
2 using source
3 on (target.a = source.a)
4 when matched then
5 update set target.b=source.b
6 when not matched then
7 insert values (source.a,source.b);
2 rows merged.
SQL> select * from source;
A B
---------- ----------
1 1
1 2
SQL>
SQL> select * from target;
A B
---------- ----------
1 2
It all seemed so simple when I read the documentation. Maybe instead of saying:
You cannot update the same row of the target table multiple times in the same MERGE statement.
Instead it should say:
You may not be able to update the same row of the target table multiple times in the same MERGE statement.
We should not count on being able to update the same row multiple times with a single MERGE statement, but clearly there are some cases in which we can. If you are like me and you get paged on a job that fails with ORA-30926 on a MERGE, it makes sense to get rid of the multiple updates on a single row because you most likely have hit a case where it is not allowed.
Bobby
About Bobby
I live in Chandler, Arizona with my wife and three daughters. I work for US Foods, the second largest food distribution company in the United States. I have worked in the Information Technology field since 1989. I have a passion for Oracle database performance tuning because I enjoy challenging technical problems that require an understanding of computer science. I enjoy communicating with people about my work.