|
|
|
compound trigger разные результаты при удалении
|
|||
|---|---|---|---|
|
#18+
Не могу понять, что за фича? Есть две таблицы. На дочерней висит compound trigger и вторичный ключ с опцией cascade. Я получаю разные результаты при удалении записи напрямую из дочерней таблицы и удалении из родительской. Сам тест: Код: 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. Наполняем данными Код: plsql 1. 2. 3. 4. 5. 6. 7. удаляем записи: Код: plsql 1. 2. 3. 4. 5. 6. Результат: 1) при удалении из потомка имеем: Код: plsql 1. 2. 2) при удалении из родителя имеем: Код: plsql 1. 2. Версия: Код: plsql 1. 2. 3. 4. 5. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.08.2018, 16:20 |
|
||
|
compound trigger разные результаты при удалении
|
|||
|---|---|---|---|
|
#18+
Курим доку: Statement triggers fired due to DELETE CASCADE and DELETE SET NULL are fired before and after the user DELETE statement, not before and after the individual enforcement statements. This prevents those statement triggers from encountering mutating errors. Т.e. при удалении из parent for each row часть compound триггерa на child выполнится как и положено а вот statement часть compound триггерa на child выполнится после завершения удаления из parent и посему vId = 0. SY. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.08.2018, 16:41 |
|
||
|
compound trigger разные результаты при удалении
|
|||
|---|---|---|---|
|
#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. 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. SY. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.08.2018, 16:55 |
|
||
|
compound trigger разные результаты при удалении
|
|||
|---|---|---|---|
|
#18+
Это да, но я вот пока не могу подобрать объяснение, что было бы плохого, если бы значение переменной было сохранено и использовано в statement секции дочернего триггера во втором примере? Ведь по сути в этом и есть смысл compound триггера. А так выходит что простым росчерком пера добавлением каскадного удаления мы может поломать реализованную ранее логику. Есть мысли? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.08.2018, 17:13 |
|
||
|
compound trigger разные результаты при удалении
|
|||
|---|---|---|---|
|
#18+
То, что написал SY - понятно. Но IMHO это действительно не прозрачно, что при добавлении ключа, ломается существующая логика PS Нарыл еще вот такое: https://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:9523633800346769343 Там вроде такой же случай, и написано что баг (там есть номер ноты, но у меня доступа на металинк нету, чтоб посмотреть) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.08.2018, 17:36 |
|
||
|
compound trigger разные результаты при удалении
|
|||
|---|---|---|---|
|
#18+
роман23tА так выходит что простым росчерком пера добавлением каскадного удаления мы может поломать реализованную ранее логику. Есть мысли? Есть твоя логика и есть логика . Логика Oracle обойти никому ненужную "table is mutating". И эта логика документирована. Так-что базируй свою логику соответственно. Если удалeние из таблицы может быть вызвано через on delete cascade, то переменные используемые как for each row так и statement level пихаем в пакет: Код: 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. 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. SY. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.08.2018, 18:25 |
|
||
|
compound trigger разные результаты при удалении
|
|||
|---|---|---|---|
|
#18+
SYто переменные используемые как for each row так и statement level пихаем в пакет:Соломон, ты забыл, что compound триггера были придуманы как раз во избежание этого? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.08.2018, 18:42 |
|
||
|
compound trigger разные результаты при удалении
|
|||
|---|---|---|---|
|
#18+
ElicSYто переменные используемые как for each row так и statement level пихаем в пакет:Соломон, ты забыл, что compound триггера были придуманы как раз во избежание этого? Не забыл. Просто eсть исключения и on cascade delete одно из них. SY. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.08.2018, 18:51 |
|
||
|
compound trigger разные результаты при удалении
|
|||
|---|---|---|---|
|
#18+
И вообще, on delete cascade/set null есть, IMHO, зло и своих девелперов за это бью иногда и материально для доходчивости. SY. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.08.2018, 18:55 |
|
||
|
compound trigger разные результаты при удалении
|
|||
|---|---|---|---|
|
#18+
SYКурим доку: Statement triggers fired due to DELETE CASCADE and DELETE SET NULL are fired before and after the user DELETE statement, not before and after the individual enforcement statements. This prevents those statement triggers from encountering mutating errors.Срабатывание чилд-триггера один раз на парент-стейтмент, а не на каждую парент-строку вполне ожидаемое поведение. Данная фраза из доки не объясняет влияние несброса состояния пакета триггера на появление mutating errors. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.08.2018, 20:00 |
|
||
|
compound trigger разные результаты при удалении
|
|||
|---|---|---|---|
|
#18+
SYElicпропущено... Соломон, ты забыл, что compound триггера были придуманы как раз во избежание этого? Не забыл. Просто eсть исключения и on cascade delete одно из них. Контекст хранить обещали в пределах одного firing statement. Но при каскадном удалении у строчного и statement-level чилд-триггера firing statement, похоже, различается. Пользуясь наработками SY: Код: 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. 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. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. нашел, что: Код: 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. 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. Видимо, нет курсора - нет и контекста, связанного с firing statement строчного child-триггера. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.08.2018, 20:40 |
|
||
|
compound trigger разные результаты при удалении
|
|||
|---|---|---|---|
|
#18+
-2-Данная фраза из доки не объясняет влияние несброса состояния пакета триггера на появление mutating errors. Elic намекaет на бабушкин мeтод борьбы с мутацией где for each row собирает PK/ROWID в пакетную коллекцию а statement level лезет с ними в таблицу. Compound триггер позволяет держать коллекцию в триггере тем самым избегая издержек типа инициализации коллекции. Однако порядок выполнения on cascade delete/set null рвет compound триггер на statement level и for each row каждый из которых выполняется в собственном контексте. Бало бы нeплохо если бы compound триггер выполнялся что-то наподобие пакетa с serially_reusable pragma. Но вызов serially_reusable из SQL запрещен. SY. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.08.2018, 21:15 |
|
||
|
compound trigger разные результаты при удалении
|
|||
|---|---|---|---|
|
#18+
Ну и до кучи еще одно косвенное подтверждение: если Код: plsql 1. оригинала заменить на инициализацию функцией вида Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. то можно видеть, что при каскадном удалении функция зовется дважды - в контексте парента (перед Child Before-statement level trigger) и чилда (перед первым вызовом строчного child-триггера). Для наглядности можно предикат удаления изменить на <=2, функция вызвана трижды: один раз в контексте парента (перед Child Before-statement level trigger) и по одному разу в контексте каждой отдельной операции удаления чилдов (перед первым вызовом строчного child-триггера с новым ключом). Таким образом: - statement-level часть compound триггера при каскадном удалении работает в контексте parent statement, а не "родного" для себя child. - контекст row-level части compound триггера переинициализируется для каждой отдельной рекурсивной операции удаления из чилда. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.08.2018, 21:24 |
|
||
|
|

start [/forum/topic.php?fid=52&msg=39682760&tid=1883641]: |
0ms |
get settings: |
9ms |
get forum list: |
15ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
207ms |
get topic data: |
8ms |
get forum data: |
2ms |
get page messages: |
50ms |
get tp. blocked users: |
1ms |
| others: | 246ms |
| total: | 544ms |

| 0 / 0 |
