Oracle 12 (update внутри select)
От: Evgeniy Skvortsov Россия  
Дата: 28.07.21 17:05
Оценка:
Есть система сбора статистики работы БД, реализована в пакете в виде набора PIPELINED функций, возвращающая данные в виде коллекции
Есть некий сервис, который вызывает сбор инфы делая SELECT * FROM TABLE(функция_аггрегатор_всех_мелких_функций) ну и потом рассылая письма если есть срабатывание по неким условиям

Появилась необходимость внутри одной из функций сохранять текущее значение некой переменной, что бы при следующем вызове этой функции сравнить прошлое значение с текущим.
Сохранять планировалось в маленькой табличке, специально созданной для хранения всяких значений для этой системы.

Понятное дело Oracle не дает это сделать.
Про PRAGMA AUTONOMOUS_TRANSACTION читал, пробовал использовать — появляется какое-то неадекватное поведение функции, логику которого мне не удалось понять
К тому же Кайт категорически не рекомендует эту штуку использовать

Вопрос, существует ли какой-то рабочий способ адекватно сделать update одной строки в табличке во время выполнения select?

Или может есть какой-то способ сохранить всего 1 число (тип данных NUMBER) во время выполнения запроса?
Re: Oracle 12 (update внутри select)
От: AndrewN Россия  
Дата: 29.07.21 06:52
Оценка: 4 (1)
Здравствуйте, Evgeniy Skvortsov, Вы писали:


ES>Вопрос, существует ли какой-то рабочий способ адекватно сделать update одной строки в табличке во время выполнения select?

ES>Или может есть какой-то способ сохранить всего 1 число (тип данных NUMBER) во время выполнения запроса?

Если действительно такой простой кейс, то непонятно, что за проблема у вас возникла с автономными транзакциями.

Напишите отдельную процедуру, которая в автономке будет вставлять (обновлять) ваше "всего одно число" и дёргайте эту процедуру из вашей PIPELINED функции.
Никаких проблем с этим возникнуть не должно. Процедуры с автономными транзакциями достаточно часто используются для логирования "всякого", что не отличается от вашего кейса ни на йоту.
Спецэффекты могут возникнуть только если вы пишете в ту же самую таблицу, из которой читает ваша основная функция.


Другой вопрос, что в общем случае подобная архитектура (когда внешний сервис дёргает PIPELINED функцию, которая пытается менять данные в БД) не выглядит корректной.

Если есть возможность (не всегда это возможно, т.к. требуется доработка внешнего сервиса в том числе), лучше вообще переделать весь процесс на асинхронные рельсы.
Чтобы внешний сервис кидал некую "заявку" на агрегацию и подготовку данных, а потом периодически проверял готовы данные или нет, если готовы — забирал результат.

Соответственно обработчик этой заявки уже не стеснён рамками SQL запроса и может делать всё что душе угодно.
--------------------------------------------------------------
Правильно заданный вопрос содержит в себе половину ответа
Re: Oracle 12 (update внутри select)
От: wildwind Россия  
Дата: 29.07.21 13:15
Оценка: +1
Здравствуйте, Evgeniy Skvortsov, Вы писали:

ES>Вопрос, существует ли какой-то рабочий способ адекватно сделать update одной строки в табличке во время выполнения select?


Нет (хаки не рассматриваем), и не надо этого хотеть.
Если в API появляется state, делайте его явным, не надо его прятать. Сервис должен знать о нем и вести себя соответственно. Например, вызывать процедуру перед (или вместо) select.
Re[2]: Oracle 12 (update внутри select)
От: Evgeniy Skvortsov Россия  
Дата: 29.07.21 13:45
Оценка:
Здравствуйте, AndrewN, Вы писали:

AN>Если действительно такой простой кейс, то непонятно, что за проблема у вас возникла с автономными транзакциями.


AN>Напишите отдельную процедуру, которая в автономке будет вставлять (обновлять) ваше "всего одно число" и дёргайте эту процедуру из вашей PIPELINED функции.

AN>Никаких проблем с этим возникнуть не должно. Процедуры с автономными транзакциями достаточно часто используются для логирования "всякого", что не отличается от вашего кейса ни на йоту.
AN>Спецэффекты могут возникнуть только если вы пишете в ту же самую таблицу, из которой читает ваша основная функция.

Да, косяк был в том, что я всю функцию, внутри которой был апдейт объявил автономной, из-за этого она выдавала странный результат
Вынес апдейт во внешнюю процедуру и в ней объявил автономную транзакцию

Спасибо. первый раз с автономной транзакцией столкнулся.
Re[2]: Oracle 12 (update внутри select)
От: Evgeniy Skvortsov Россия  
Дата: 29.07.21 14:04
Оценка:
Здравствуйте, wildwind, Вы писали:

W>Если в API появляется state, делайте его явным, не надо его прятать. Сервис должен знать о нем и вести себя соответственно. Например, вызывать процедуру перед (или вместо) select.


Да сервису дела нет до потрохов, он делает select * from table(имя_функции)
а внутри этой функции select и union из других функций возвращающие данные
Вот внутри одной из этих функций нужно сохранить значение.
Вроде уже разобрался.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.