|
Доп. действия во время MERGE
|
|||
---|---|---|---|
#18+
Делаю обыкновенный MERGE: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18.
Если мне надо что то делать дополнительно, например, делать insert'ы в какую-нибудь ещё таблицу при UPDATE и при INSERT этого MERGE, то как это лучше сделать? Что то примерно такое надо: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20.
... |
|||
:
Нравится:
Не нравится:
|
|||
04.10.2021, 12:22 |
|
Доп. действия во время MERGE
|
|||
---|---|---|---|
#18+
verter Если мне надо что то делать дополнительно в триггере insert ... ..... stax ... |
|||
:
Нравится:
Не нравится:
|
|||
04.10.2021, 13:19 |
|
Доп. действия во время MERGE
|
|||
---|---|---|---|
#18+
verter, Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9.
... |
|||
:
Нравится:
Не нравится:
|
|||
04.10.2021, 13:28 |
|
Доп. действия во время MERGE
|
|||
---|---|---|---|
#18+
Stax verter Если мне надо что то делать дополнительно в триггере insert ... ..... stax в триггере то понятно, но, к сожалению, есть ограничение на разработку, нельзя использовать триггеры. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.10.2021, 14:27 |
|
Доп. действия во время MERGE
|
|||
---|---|---|---|
#18+
Anton_Demin verter, Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9.
Объём таблиц очень большой, циклами будет очень медленно. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.10.2021, 14:28 |
|
Доп. действия во время MERGE
|
|||
---|---|---|---|
#18+
verterесть ограничение на разработку Значит спрашивай того, кто эти ограничения установил. У него же наверняка был план... Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
04.10.2021, 14:55 |
|
Доп. действия во время MERGE
|
|||
---|---|---|---|
#18+
А если сделать функцию, в которую нужные для вставки параметры и она возвращает нужное значение для поля в мердже. так сработает? Код: plsql 1. 2. 3. 4. 5. 6.
... |
|||
:
Нравится:
Не нравится:
|
|||
04.10.2021, 16:12 |
|
Доп. действия во время MERGE
|
|||
---|---|---|---|
#18+
barrabas, И получишь ORA-14551: cannot perform a DML operation inside a query ... |
|||
:
Нравится:
Не нравится:
|
|||
04.10.2021, 17:13 |
|
Доп. действия во время MERGE
|
|||
---|---|---|---|
#18+
точно? попробовал быстро на инсерте не получил Код: plsql 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.
Код: 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.
... |
|||
:
Нравится:
Не нравится:
|
|||
04.10.2021, 17:23 |
|
Доп. действия во время MERGE
|
|||
---|---|---|---|
#18+
merge тоже без ошибки по условию доп действия с другой таблицей же (INSERT INTO TBL_LOG1 VALUES(...)) Код: plsql 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.
... |
|||
:
Нравится:
Не нравится:
|
|||
04.10.2021, 17:39 |
|
Доп. действия во время MERGE
|
|||
---|---|---|---|
#18+
barrabas А если сделать функцию, в которую нужные для вставки параметры и она возвращает нужное значение для поля в мердже. так сработает? Код: plsql 1. 2. 3. 4. 5.
идея классная! но будет ли быстро работать на больших таблицах? ... |
|||
:
Нравится:
Не нравится:
|
|||
04.10.2021, 17:42 |
|
Доп. действия во время MERGE
|
|||
---|---|---|---|
#18+
если нужно еще и с таблицами участвующими в мердже, то думаю можно через временные таблицы или коллекции в пакетных переменных (по типу обхода ошибки с мутацией). накопить что должен сделать и сделать после мерджа сразу. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.10.2021, 17:43 |
|
Доп. действия во время MERGE
|
|||
---|---|---|---|
#18+
verter, все зависит что именно нужно. может реально накопить в памяти в коллекции, которая заполняется в функции, а потом вставить через forall. попробуй по разному ... |
|||
:
Нравится:
Не нравится:
|
|||
04.10.2021, 17:45 |
|
Доп. действия во время MERGE
|
|||
---|---|---|---|
#18+
barrabas verter, все зависит что именно нужно. может реально накопить в памяти в коллекции, которая заполняется в функции, а потом вставить через forall. попробуй по разному если очень много, то forall прям в функции по определенному кол-ву записей с очисткой коллекции, а потом в конце остатки. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.10.2021, 17:47 |
|
Доп. действия во время MERGE
|
|||
---|---|---|---|
#18+
barrabas, Я попробовал сделать в MERGE запись в лог функцией. Всё сработало хорошо, спасибо. НО! Почему то вызов функции срабатывает 2 раза. Соответственно и в таблице лога появляется 2-е одинаковые записи. Вот я выполняю MERGE: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
Допустим срабатывает блок с INSERT, т.е. WHEN NOT MATCHED Но в TMP_L1 появляются 2-е записи, т.е. TestINS() срабатывает 2 раза. Как такое может быть? Отдельно TestINS() вызывал - записывает 1 раз. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.10.2021, 14:04 |
|
Доп. действия во время MERGE
|
|||
---|---|---|---|
#18+
verter barrabas, Я попробовал сделать в MERGE запись в лог функцией. Всё сработало хорошо, спасибо. НО! Почему то вызов функции срабатывает 2 раза. Соответственно и в таблице лога появляется 2-е одинаковые записи. Вот я выполняю MERGE: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
Допустим срабатывает блок с INSERT, т.е. WHEN NOT MATCHED Но в TMP_L1 появляются 2-е записи, т.е. TestINS() срабатывает 2 раза. Как такое может быть? Отдельно TestINS() вызывал - записывает 1 раз. ну видимо оракл вычисляет значение функции для всего мерджа заранее. можно попробовать deterministic указать у функции или через пакетную переменную сделать проверку на некий уникальный ID вызова. короче, выкрутится то можно но будет мостр ) вместо пакетной переменной можно sys_context еще попробовать. на вход что-то уникальное для записи, например склейку полей из ON. сохранять в контекст/переменную и проверять что изменилась, только тогда писать в лог ... |
|||
:
Нравится:
Не нравится:
|
|||
07.10.2021, 14:08 |
|
Доп. действия во время MERGE
|
|||
---|---|---|---|
#18+
для интереса, если для инсерта и апдейте сделать функции с разным именем, тоже 2 раза будет? ... |
|||
:
Нравится:
Не нравится:
|
|||
07.10.2021, 14:15 |
|
Доп. действия во время MERGE
|
|||
---|---|---|---|
#18+
barrabas для интереса, если для инсерта и апдейте сделать функции с разным именем, тоже 2 раза будет? deterministic помог избавиться от двойной записи, спасибо! Но есть ещё одна проблема, которую я не сразу заметил, потому что проверял по отдельности вызовы TestINS() - при апдейте отдельно и при инсёрте отдельно. А теперь когда вставил вызов TestINS() в оба, то после мержа появляются записи после инсёрта и апдейта, несмотря на то, что срабатывает какая то одна из секций мержа - либо MUCHED либо NOT MUCHED. Я проверял когда MUCHED, т.е. должен был сработать вызов TestINS() только 1 раз с значениями для апдейта, но сработало 2 раза - и для апдейта и для инсёрта. Т.о. Oracle до мержа вызывает функции из обоих секций каким то образом. Пробывал сделать отдельные функции TestINS_on_I и TestINS_on_U - не помогает, срабатывают одновременно обе. Ну вот как так? ... |
|||
:
Нравится:
Не нравится:
|
|||
07.10.2021, 14:42 |
|
Доп. действия во время MERGE
|
|||
---|---|---|---|
#18+
ну и соответственно если убрать determenistic, то в логе будут 4 записи - 2 для инсёрта и 2 для апдейта хотя в результате мержа происходит обновление 1 записи ... |
|||
:
Нравится:
Не нравится:
|
|||
07.10.2021, 14:46 |
|
Доп. действия во время MERGE
|
|||
---|---|---|---|
#18+
verter, проверять уникальность тогда остаётся в USING сделать поле с sys_guid или что-то униканое. передавать в функцию, в ней проверять в контексте или переменной пакетной, есть ли такое значение, если нет, то записываем в контекст его и пишем в лог. если происходит повторный вызов, мы видим что такая запись уже прилетала в функции и пропускам. учесть что у апдейта может быть WHERE, т.е. в в функцию нужно передать флаг скип сразу вычислив через case например ... |
|||
:
Нравится:
Не нравится:
|
|||
07.10.2021, 14:54 |
|
Доп. действия во время MERGE
|
|||
---|---|---|---|
#18+
я вообще такое решение не применял никогда. просто интересно как задача показалась. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.10.2021, 14:57 |
|
Доп. действия во время MERGE
|
|||
---|---|---|---|
#18+
verter, 1. Разделить insert и update 2 insert... returning ... bulk collect into... 3. update ... returning ... bulk collect into... 4. insert into log.... ... |
|||
:
Нравится:
Не нравится:
|
|||
07.10.2021, 15:54 |
|
Доп. действия во время MERGE
|
|||
---|---|---|---|
#18+
если отвлечься от задачи "действия во время merge". а надо мёрджить реально большие таблицы с миллионами записей и нет жесткого требования закомитить все разом, то я бы еще подробил по дням/месяцам/годам (или что там есть и сколько в данных в порциях) + dbms_application_info.set_session_longops. ползунок в GUI или проценты в логе, они успокаивают что-ли ... ... |
|||
:
Нравится:
Не нравится:
|
|||
07.10.2021, 16:14 |
|
Доп. действия во время MERGE
|
|||
---|---|---|---|
#18+
ну и dbms_parallel_execute или потоки с клиента ... |
|||
:
Нравится:
Не нравится:
|
|||
07.10.2021, 16:16 |
|
|
start [/forum/topic.php?fid=52&tid=1879842]: |
0ms |
get settings: |
17ms |
get forum list: |
8ms |
check forum access: |
1ms |
check topic access: |
1ms |
track hit: |
38ms |
get topic data: |
3ms |
get forum data: |
1ms |
get page messages: |
462ms |
get tp. blocked users: |
0ms |
others: | 2479ms |
total: | 3010ms |
0 / 0 |