Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Oracle [игнор отключен] [закрыт для гостей] / merge и ORA-30926 / 24 сообщений из 24, страница 1 из 1
21.12.2010, 21:23
    #37028265
Жук в муравейнике
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge и ORA-30926
Код: 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
21.12.2010, 21:24
    #37028268
Жук в муравейнике
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge и ORA-30926
Код: 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
21.12.2010, 23:16
    #37028442
_Nikotin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge и ORA-30926
Из этой цитаты становится понятно такое поведение:
Сергей Маркеленков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
22.12.2010, 00:08
    #37028521
-2-
-2-
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge и ORA-30926
_NikotinИз этой цитаты становится понятно такое поведениеВот "такое"?
Код: plaintext
 2  rows merged.                    -- Ошибки не получаем
...
Рейтинг: 0 / 0
22.12.2010, 00:22
    #37028552
_Nikotin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge и ORA-30926
-2-,

Я так понимаю что если последовательность обновления была 0->0->1 , то CR и CURRENT версии строк совпадают в обоих случаях.
...
Рейтинг: 0 / 0
22.12.2010, 00:51
    #37028595
-2-
-2-
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge и ORA-30926
_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
22.12.2010, 02:02
    #37028689
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge и ORA-30926
-2-You cannot update the same row of the target table multiple times in the same MERGE statement.
Если нельзя, но очень хочется - то можно :)
...
Рейтинг: 0 / 0
22.12.2010, 02:23
    #37028701
-2-
-2-
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge и ORA-30926
andrey_anonymousЕсли нельзя, но очень хочется - то можно :)В 11.2 лазейку прикрыли.
...
Рейтинг: 0 / 0
22.12.2010, 07:19
    #37028732
_Nikotin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge и ORA-30926
-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
20.05.2011, 18:37
    #37272124
Awkward
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge и ORA-30926
Привет!

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

Повторил тест ТС на 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
20.05.2011, 19:49
    #37272221
orawish
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge и ORA-30926
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
21.05.2011, 10:04
    #37272487
Awkward
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge и ORA-30926
orawish,

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

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

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

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

самое главное,что я точно не пойму критерий, по которому работает merge: когда он делает exception в случае конфликта в данных, а когда нет
...
Рейтинг: 0 / 0
21.05.2011, 11:19
    #37272528
donner-gms
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge и ORA-30926
_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
21.05.2011, 13:37
    #37272633
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge и ORA-30926
donner-gmsахренеть! а полностью статью можно эту почитать?
Поищите по форуму обсуждения "микрооткатов" и "statement restart". Кроме собственно обсуждений Сергей Маркеленков вроде давал ссылку на эту статью.
...
Рейтинг: 0 / 0
21.05.2011, 18:29
    #37272788
Эталон Этанолович
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge и ORA-30926
Здесь исправлено несколько опечаток по сравнению со статьей, канувшей в лету (?) вместе с oramag.ru. В сноске 38 к команде MERGE на стр. 27 следовало бы добавить, что такое поведение следует рассматривать как Bug.
...
Рейтинг: 0 / 0
22.05.2011, 16:41
    #37273310
dbms_photoshop
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge и ORA-30926
Эталон Этанолович,

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

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

Помогите, пожалуйста, разобраться с примером "мини-отката", приведенный в статье Сергея Маркеленкова "Алгоритм “мини-откатов” в 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
Период между сообщениями больше года.
18.07.2017, 14:56
    #39490860
RMagistr2015
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge и ORA-30926
-2-,

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

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

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

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

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

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


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