|
Очистка таблицы возвращаемой из функции
|
|||
---|---|---|---|
#18+
Здравствуйте, необходим совет для решения следующей проблемы: Выполняется некая функция. (Пример снизу отношения к этой функции не имеет, но вполне приемлем для демонстрации проблемы) В ходе своей работы она выполняет некоторые действия (копирование или перемещение сущностей) и после каждого такого действия вставляет с помощью конструкций RETURN NEXT и RETURN QUERY строки в возвращаемую таблицу. В нескольких местах этой функции вызывается другая функция (будем называть ее "внутренней"), которая может вернуть значение, обозначающее ошибку. Если внутренняя функция вернула ошибку, то надо откатить все изменения внесенные внешней функцией и вернуть из нее таблицу всего с одной строкой, обозначающей ошибку. Откатываю изменения я, с помощью RAISE EXCEPTION, затем, чтобы вернуть строку с ошибкой, перехватываю исключение EXCEPTION WHEN SQLSTATE и добавляю в возвращаемую таблицу строку об ошибке. Проблема в том, что RAISE EXCEPTION отменяет изменения только в таблицах, а возвращаемая таблица забивается строками, которые добавлялись в процессе работы функции. Как это можно исправить? (Т.е., как вернуть только одну строку об ошибке из блока перехвата исключений?) Результат работы приведенного ниже примера в прикрепленном изображении. Дополнительный вопрос, правильно я понимаю, что RAISE EXCEPTION всегда отменяет все действия произведенные функцией, в независимости от того перехватываем мы исключения или нет? Код: sql 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.
... |
|||
:
Нравится:
Не нравится:
|
|||
27.08.2017, 00:03 |
|
Очистка таблицы возвращаемой из функции
|
|||
---|---|---|---|
#18+
NumberOne, упасть в первой, отменив её возврат (оно даже не пайп, а накопитель) и вывести нужное -- во второй. примерно так (удаляю все ненужное) Код: sql 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.
или же начинать возврат только после , но никак не до обрабатываемого исключения, ветвясь на исключении между 2-мя случаями возвратов. (например набирать будущий возврат в массивы , но не возвращать в случае исключения. ... |
|||
:
Нравится:
Не нравится:
|
|||
27.08.2017, 10:09 |
|
Очистка таблицы возвращаемой из функции
|
|||
---|---|---|---|
#18+
NumberOneДополнительный вопрос, правильно я понимаю, что RAISE EXCEPTION всегда отменяет все действия произведенные функцией, в независимости от того перехватываем мы исключения или нет? неправильно во первых не все. во вторых только скл- стейтменты от предыдущего сейвпойнта . предыдущего относительно точки перехвата исключения . а все, что поменялось в переменных plpgsql -- все там и будет. то же -- с возвратами. если вы не окончательно упали, ессно. тогда весь возврат накроется. (если был бы пайп и вы из него фетчили, помаленьку, но до ексепшена... то было бы интересно, как провзаимодействует например return query с предлагаемой оберткой --- там могли бы прорезаться особости реализации пайпов) RTFM, короче. ... |
|||
:
Нравится:
Не нравится:
|
|||
27.08.2017, 10:22 |
|
Очистка таблицы возвращаемой из функции
|
|||
---|---|---|---|
#18+
qwwq, Спасибо за информацию, пожалуй воспользуюсь способом с многомерным массивом ... |
|||
:
Нравится:
Не нравится:
|
|||
27.08.2017, 16:18 |
|
Очистка таблицы возвращаемой из функции
|
|||
---|---|---|---|
#18+
Переделал с массивами. Теперь появился новый вопрос. Как выгоднее сделать возврат результирующей таблицы перед последним RETURN. В рабочей функции у меня 4 массива для хранения полей возвращаемой таблицы, в примере снизу 2 массива. Можно использовать unnest для всех массивов, как в примере снизу RETURN QUERY SELECT t.a, t.b FROM (SELECT CAST('00000000-0000-0000-0000-000000000077' AS uuid) AS a, unnest(test_ids) AS b) AS t; а можно сделать перебор в цикле по массивам, что будет быстрее? Код: sql 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.
... |
|||
:
Нравится:
Не нравится:
|
|||
27.08.2017, 18:02 |
|
Очистка таблицы возвращаемой из функции
|
|||
---|---|---|---|
#18+
NumberOne а можно сделать перебор в цикле по массивам, что будет быстрее? дык проверьте. я лично предпочитаю не резать кошке хвост по частям, там где это возможно. а использовать встроенные аггрегаты. (а-ля стринг--буферы) можете например проверить такую штуку: Код: sql 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.
супротив вашей: Код: sql 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.
--всего-то 10000 лишних присвоений , казалось бы. (агргегаты там вообще не играют роли, думается) ... |
|||
:
Нравится:
Не нравится:
|
|||
27.08.2017, 22:25 |
|
|
start [/forum/topic.php?fid=53&fpage=67&tid=1996265]: |
0ms |
get settings: |
8ms |
get forum list: |
14ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
35ms |
get topic data: |
14ms |
get forum data: |
3ms |
get page messages: |
42ms |
get tp. blocked users: |
1ms |
others: | 16ms |
total: | 141ms |
0 / 0 |