powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / merge и ORA-30926
24 сообщений из 24, страница 1 из 1
merge и ORA-30926
    #37028265
Фотография Жук в муравейнике
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
SQL> create table  tst_act (id number, flag number);

Table created.

SQL> create table  tst_map (id number, map_id number, flag number);

Table created.

SQL> delete from tst_act;

 0  rows deleted.

SQL> insert into tst_act values ( 1001 , 0 );

 1  row created.

SQL> commit;

Commit complete.

SQL> select * from tst_act;

        ID       FLAG
---------- ----------
       1001            0 

SQL> delete from tst_map;

 0  rows deleted.

SQL> insert into tst_map values ( 1001 ,- 1 , 0 );    -- Первым загрузим нулик

 1  row created.

SQL> insert into tst_map values ( 1001 ,- 1 , 1 );

 1  row created.

SQL> commit;

Commit complete.

SQL> select * from tst_map;

        ID     MAP_ID       FLAG
---------- ---------- ----------
       1001          - 1            0 
       1001          - 1            1 

SQL> merge into tst_act a
   2   using (select distinct m.* from tst_map m) m
   3   on (a.id = m.id)
   4   when matched then  update
   5                              set a.flag = m.flag;

 2  rows merged.                    -- Ошибки не получаем

SQL> select * from tst_act;

        ID       FLAG
---------- ----------
       1001            1 

SQL> merge into tst_act a
   2   using (select distinct m.* from tst_map m) m
   3   on (a.id = m.id)
   4   when matched then  update
   5                              set a.flag = m.flag;
merge into tst_act a
           *
ERROR at line  1 :
ORA- 30926 : unable to get a stable set of rows in the source tables    -- Со второй попытки ловим

Ещё разок

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
SQL> drop table tst_act;

Table dropped.

SQL> drop table tst_map;

Table dropped.

SQL> create table  tst_act (id number, flag number);

Table created.

SQL> create table  tst_map (id number, map_id number, flag number);

Table created.

SQL> delete from tst_act;

 0  rows deleted.

SQL> insert into tst_act values ( 1001 , 1 );

 1  row created.

SQL> commit;

Commit complete.

SQL> select * from tst_act;

        ID       FLAG
---------- ----------
       1001            1 

SQL> delete from tst_map;

 0  rows deleted.

SQL> insert into tst_map values ( 1001 ,- 1 , 1 );  -- Единичку загрузим раньше

 1  row created.

SQL> insert into tst_map values ( 1001 ,- 2 , 0 );

 1  row created.

SQL> commit;

Commit complete.

SQL> select * from tst_map;

        ID     MAP_ID       FLAG
---------- ---------- ----------
       1001          - 1            1 
       1001          - 2            0 

SQL>
SQL> merge into tst_act a
   2   using (select distinct m.* from tst_map m) m
   3   on (a.id = m.id)
   4   when matched then  update
   5                              set a.flag = m.flag;
merge into tst_act a
           *
ERROR at line  1 :
ORA- 30926 : unable to get a stable set of rows in the source tables     -- Ошибку ловим с первого запуска


SQL> select * from tst_act;

        ID       FLAG
---------- ----------
       1001            1 

SQL> merge into tst_act a
   2   using (select distinct m.* from tst_map m) m
   3   on (a.id = m.id)
   4   when matched then  update
   5                              set a.flag = m.flag;
merge into tst_act a
           *
ERROR at line  1 :
ORA- 30926 : unable to get a stable set of rows in the source tables
...
Рейтинг: 0 / 0
merge и ORA-30926
    #37028268
Фотография Жук в муравейнике
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
SQL> select * from v$version;

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release  10 . 2 . 0 . 4 . 0  - 64bi
PL/SQL Release  10 . 2 . 0 . 4 . 0  - Production
CORE     10 . 2 . 0 . 4 . 0       Production
TNS for Linux: Version  10 . 2 . 0 . 4 . 0  - Production
NLSRTL Version  10 . 2 . 0 . 4 . 0  - Production
...
Рейтинг: 0 / 0
merge и ORA-30926
    #37028442
_Nikotin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Из этой цитаты становится понятно такое поведение:
Сергей Маркеленков3) Есть еще один интересный нюанс команды MERGE, который можно обнаружить, выполнив тест 3. Если команда выполняется в режиме изолированности READ COMMITED и производится попытка повторного обновления одной и той же строки (то есть, каждой строке целевой таблицы согласно условию во фразе ON соответствует более одной строки в источнике строк), то происходит откат команды, блокировка всех строк, подлежащих обновлению и опять неудачное обновление . В Oracle до версии 8.1.6 такая команда заканчивалась ошибкой ORA-00600 [13012], а в Oracle 8.1.6 и выше – сообщением об ошибке ORA-30926 “unable to get a stable set of rows in the source tables”. При этом создается трассировочный файл с фразой “updexe: Table X Code 1 Cannot update even though all locked…” и выдается содержимое CR и CURRENT-блоков, в которых находится сравниваемая строка, вызвавшая ошибку. После анализа этого файла становится понятно, что в сравнении CR и CURRENT-версий строк участвуют как минимум байты блокировки из заголовков строк. Обратите внимание, что, если в базе данных нет DML-активности, то SCN, с которыми происходит блокировка и финальная попытка обновления, может быть равен SCN на момент старта.
...
Рейтинг: 0 / 0
merge и ORA-30926
    #37028521
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_NikotinИз этой цитаты становится понятно такое поведениеВот "такое"?
Код: plaintext
 2  rows merged.                    -- Ошибки не получаем
...
Рейтинг: 0 / 0
merge и ORA-30926
    #37028552
_Nikotin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
-2-,

Я так понимаю что если последовательность обновления была 0->0->1 , то CR и CURRENT версии строк совпадают в обоих случаях.
...
Рейтинг: 0 / 0
merge и ORA-30926
    #37028595
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_NikotinЯ так понимаюв доке достаточно однозначно написаноSQL ReferenceMERGE is a deterministic statement. You cannot update the same row of the target table multiple times in the same MERGE statement.
...
Рейтинг: 0 / 0
merge и ORA-30926
    #37028689
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
-2-You cannot update the same row of the target table multiple times in the same MERGE statement.
Если нельзя, но очень хочется - то можно :)
...
Рейтинг: 0 / 0
merge и ORA-30926
    #37028701
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymousЕсли нельзя, но очень хочется - то можно :)В 11.2 лазейку прикрыли.
...
Рейтинг: 0 / 0
merge и ORA-30926
    #37028732
_Nikotin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
-2-_NikotinЯ так понимаюв доке достаточно однозначно написаноSQL ReferenceMERGE is a deterministic statement. You cannot update the same row of the target table multiple times in the same MERGE statement.
Я и не спорю что это баг. Я говорил о причинах такого поведения.
...
Рейтинг: 0 / 0
merge и ORA-30926
    #37272124
Awkward
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Привет!

Попробую возобновить тему.

Повторил тест ТС на Oracle 11R2, все так же.

Получается тогда, что ЕСЛИ есть ситуация:

a) выполняется
merge into A using B on (A.col1 = B.col1)
when matched then update... when not matched then insert...

б) в B есть дубликаты по некоторому значению col1 и в A есть строка (либо строки, это неважно) с таким значением col1 (т.е. должен отработать when matched then update)

ТО

Невозможно точно сказать, как будет вести себя merge, т.е.
будет ORA-30926, либо все-таки пройдет update?

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

Возможно, кто-то уже сталкивался с такой неопределенностью, и отказался от использования merge?

Ответ на это вопрос в других темах не нашел.
...
Рейтинг: 0 / 0
merge и ORA-30926
    #37272221
Фотография orawish
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AwkwardПривет!

Попробую возобновить тему.

Повторил тест ТС на Oracle 11R2, все так же.

Получается тогда, что ЕСЛИ есть ситуация:

a) выполняется
merge into A using B on (A.col1 = B.col1)
when matched then update... when not matched then insert...

б) в B есть дубликаты по некоторому значению col1 и в A есть строка (либо строки, это неважно) с таким значением col1 (т.е. должен отработать when matched then update)

ТО

Невозможно точно сказать, как будет вести себя merge, т.е.
будет ORA-30926, либо все-таки пройдет update?

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

Возможно, кто-то уже сталкивался с такой неопределенностью, и отказался от использования merge?

Ответ на это вопрос в других темах не нашел.
не вижу в вашем примере аргументов, чтобы отказываться от merge.

что может означать поведение, которого вы хотите? в случае конфликта внутри вставляемых данных - вставить то, пофиг что?
using - он же ваш. ну и пишите using (select агрегированное_что_надо .. group by ключик_слияния)
...
Рейтинг: 0 / 0
merge и ORA-30926
    #37272487
Awkward
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
orawish,

спасибо за ответ!

конечно, цель не в том,чтобы в случае конфликта вставить что попало
наоборот, я от merge ожидал такого поведения: в случае конфликта он на 100% выбрасывает exception
т.е. также, как PK на таблице в случае попытки добавить существующее значение гарантированно выдаст exception

я даже был уверен в том, что merge так и работает, но оказалось, что он может и не выбросить исключение в таком случае

конечно, согласен с Вами, что надо самому позаботиться, чтобы в using не было дубликатов по ключу
просто в моем случае речь идет об ETL, объемы данных большие, преобразований над данными много, поэтому иногда удобно, чтобы merge был чем-то вроде "динамического констрейнта"

самое главное,что я точно не пойму критерий, по которому работает merge: когда он делает exception в случае конфликта в данных, а когда нет
...
Рейтинг: 0 / 0
merge и ORA-30926
    #37272528
donner-gms
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_NikotinИз этой цитаты становится понятно такое поведение:
Сергей Маркеленков3) Есть еще один интересный нюанс команды MERGE, который можно обнаружить, выполнив тест 3. Если команда выполняется в режиме изолированности READ COMMITED и производится попытка повторного обновления одной и той же строки (то есть, каждой строке целевой таблицы согласно условию во фразе ON соответствует более одной строки в источнике строк), то происходит откат команды, блокировка всех строк, подлежащих обновлению и опять неудачное обновление . В Oracle до версии 8.1.6 такая команда заканчивалась ошибкой ORA-00600 [13012], а в Oracle 8.1.6 и выше – сообщением об ошибке ORA-30926 “unable to get a stable set of rows in the source tables”. При этом создается трассировочный файл с фразой “updexe: Table X Code 1 Cannot update even though all locked…” и выдается содержимое CR и CURRENT-блоков, в которых находится сравниваемая строка, вызвавшая ошибку. После анализа этого файла становится понятно, что в сравнении CR и CURRENT-версий строк участвуют как минимум байты блокировки из заголовков строк. Обратите внимание, что, если в базе данных нет DML-активности, то SCN, с которыми происходит блокировка и финальная попытка обновления, может быть равен SCN на момент старта.

ахренеть! а полностью статью можно эту почитать?
...
Рейтинг: 0 / 0
merge и ORA-30926
    #37272633
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
donner-gmsахренеть! а полностью статью можно эту почитать?
Поищите по форуму обсуждения "микрооткатов" и "statement restart". Кроме собственно обсуждений Сергей Маркеленков вроде давал ссылку на эту статью.
...
Рейтинг: 0 / 0
merge и ORA-30926
    #37272788
Эталон Этанолович
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здесь исправлено несколько опечаток по сравнению со статьей, канувшей в лету (?) вместе с oramag.ru. В сноске 38 к команде MERGE на стр. 27 следовало бы добавить, что такое поведение следует рассматривать как Bug.
...
Рейтинг: 0 / 0
merge и ORA-30926
    #37273310
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Эталон Этанолович,

Сергей, спасибо!
...
Рейтинг: 0 / 0
merge и ORA-30926
    #37273866
Awkward
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Эталон Этанолович,

спасибо, статья очень интересная!
...
Рейтинг: 0 / 0
merge и ORA-30926
    #37275887
Эталон Этанолович
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Только учтите, что на версиях 11g тесты не производились. Там могло что-то поменяться. Если кому не лень провести тесты в 11.1 и 11.2 - интересно было бы узнать, изменилось что-то или нет. Например, поведение MERGE исправили или нет
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
merge и ORA-30926
    #38992517
F_L_E_X
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем привет!

Помогите, пожалуйста, разобраться с примером "мини-отката", приведенный в статье Сергея Маркеленкова "Алгоритм “мини-откатов” в Oracle или еще раз о Write Consistency".
Статья прикреплена в сообщении ув. Эталона Этаноловича, за что отдельная благодарность.
В начала выполнения сеанса "Long update", он останавливается на строке id=3 и ждет. В это время изменяется значение строки id=5, в следствии чего она перестает удолетворять предикату команды update. После этого, строка id=3 разблокируется и update доходит до строки id=5, сравнивает значение, полученное при согласованном чтении в начале старта, с текущим значением . Они не равны. Таким образом, выясняется, что требуется выполнить "мини-откат". Идет отмена всех изменений и снятие всех блокировок установленных до этого момента.
Вопрос : если бы после строки id=5, были строки удовлетворяющие предикату команды update (к примеру, значение строки id=8 было бы 15), сеанс "Long update" дошел бы до нее? Он попытался бы поставить на нее блокировку?
Хочется понять, «мини-откат» начинается сразу же после того, как обнаруживается не равенство начального и текущего значений и дальше update не смотрит на строки, которые удовлетворяют предикату команды? Или, после обнаружения не равенства, update все же «пробежит» по всем оставшимся строкам и только потом запустить «мини-откат»

Теперь интересует момент со строкой id=10.
Вопрос : После того, как второй «накат» команды update аналогично увидит, что значения отличаются на начало и текущий момент, он также запустит новый «мини-откат»? Или играет значение, что update «завис» непосредственно на той строке которая модифицировалась и в итоге перестала удовлетворять предикату?
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
merge и ORA-30926
    #39490860
RMagistr2015
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
-2-,

Что-то у меня не получается сделать так ((((
добавляю rows merged в код как указывали, и он всё время выдаёт ошибку ((((
Что делать? Как решить эту проблему?
...
Рейтинг: 0 / 0
merge и ORA-30926
    #39491307
RMagistr2015,

Вы признаны лучшим и самым активным гробокопателем года!
Поздравляем!
...
Рейтинг: 0 / 0
merge и ORA-30926
    #39491408
RMagistr2015
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Смотритель оград усопшихRMagistr2015,

Вы признаны лучшим и самым активным гробокопателем года!
Поздравляем!

Да ладно тебе )))) Я не достоин )))) Лучше скажи как победить эту ошибку, а то таблицы не синхронизируются ((( И это беда ((((
...
Рейтинг: 0 / 0
merge и ORA-30926
    #39494370
Фотография env
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
RMagistr2015,

Чего ты куда добавляешь?
Код показывай.
...
Рейтинг: 0 / 0
merge и ORA-30926
    #39494417
RMagistr2015
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
envRMagistr2015,

Чего ты куда добавляешь?
Код показывай.
Проехала тема, решил через курсор, спасибо
...
Рейтинг: 0 / 0
24 сообщений из 24, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / merge и ORA-30926
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]