Oracle: имитация триггера "пост-фиксации" - PullRequest
4 голосов
/ 22 сентября 2010

Как я могу получить эквивалент триггера "при фиксации" после вставки некоторых строк в таблицу?

После вставки нескольких строк в таблицу я хотел бы отправить внешнему процессу сообщение о том, что есть строки, готовые для обработки. Использование триггера на уровне операторов приводит к одному сообщению на одну вставку, и я хотел бы отправить только одно сообщение о том, что «есть строки, которые нужно обработать».

Ответы [ 4 ]

7 голосов
/ 22 сентября 2010

Создать работу. На самом деле он не будет отправлен, пока не произойдет коммит. (Примечание: DBMS_SCHEDULER обычно лучше, чем DBMS_JOB, но в этом случае вам нужно использовать старый пакет DBMS_JOB.)

declare
  jobnumber number;
begin
  dbms_job.submit(job => jobnumber, what => 'insert into test values(''there are rows to process'');');
  --do some work here...
  commit;
end;
/
3 голосов
/ 20 апреля 2011

Поскольку вам нужно запустить внешний процесс, обратите внимание на DBMS_ALERT вместо DBMS_JOB.

Внешний процесс будет активно прослушивать предупреждение, вызывая хранимую процедуру. Хранимая процедура вернется сразу после того, как предупреждение будет сигнализировано и передано.

Обратите внимание, что DBMS_ALERT является устройством сериализации. Таким образом, несколько сеансов, сигнализирующих одно и то же имя оповещения, будут блокироваться так же, как если бы они обновляли одну и ту же строку в таблице.

1 голос
/ 22 сентября 2010

Используя Oracle Advanced Queuing, вы можете поставить в очередь массив записей со слушателем в таблице очередей.

Записи будут загружены, и слушатель сможет затем запустить любой процесс, который вы пожелаете, даже вызов веб-службы.

http://download.oracle.com/docs/cd/B28359_01/appdev.111/b28419/d_aq.htm#i1001754

1 голос
/ 22 сентября 2010

Вы можете установить флаг, чтобы сказать «Я отправил сообщение».Чтобы убедиться, что вы «сбросили» флаг при коммите, используйте dbms_transaction.local_transaction_id, тогда вы можете просто сделать

IF v_flag IS NULL OR dbms_transaction.local_transaction_id != v_flag THEN
  v_flag := dbms_transaction.local_transaction_id;
  generate message
END IF;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...