Oracle Процесс APEX ARP не выполнен только из-за сбоя другого процесса? - PullRequest
0 голосов
/ 16 апреля 2020
  1. Вы потрясающее сообщество. Это первый раз, когда я не смог найти ответ на свои вопросы, и у меня были миллионы

  2. Успокойся. Я супер нуб, и я уже обиделся за то, что заставил тебя тратить свое время на мой глупый вопрос

  3. Так ... Я пытаюсь сделать приложение с oracle apex. У меня есть форма с интерактивным отчетом для таблицы1. На странице формы у меня есть 3 процесса в следующем порядке:

    • Automati c Row Processing (DML), который апекс автоматически сделал для меня,
    • pl / sql процесс Я сделал и
    • вершина процесса сброса страницы.

ARP обновляет, создает и удаляет и запускается любой из кнопок (СОХРАНИТЬ, СОЗДАТЬ, УДАЛИТЬ).

Мой процесс удаляет строку в другой таблице2 и выполняется при нажатии DELETE и ITEM1 не является нулевым (потому что в ITEM1 я сохранил PK для строки во второй таблице).

Последний процесс - это обычная страница сброса, которая должна очищать все значения элементов при нажатии кнопки DELETE.

Точка срабатывания по умолчанию "Обрабатывается" для всех 3.

Иногда мой процесс завершается неудачно (и возвращает установленную мной ошибку) из-за ограничения FK.

Теперь вот мысль: если мой процесс завершится неудачно, oder 2, похоже, не будет выполнен. Это возможно? Если я устанавливаю условие (должно быть выполнено) моего процесса на Никогда, то другие 2 работают. Чего мне не хватает?

1 Ответ

0 голосов
/ 16 апреля 2020

Вы ничего не упускаете.

Когда вы нажимаете sh кнопку, которая запускает эти процессы, они совершают транзакцию . Если какой-либо из них вызывает ошибку, все они (выполненные до сих пор) откатываются.

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

Тривиальный (и не самый лучший) вариант - игнорировать возможные ошибки, например,

begin
  delete from child_table where id = :P1_ITEM1;
exception
  when others then null;   --> ignore any errors
end;

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

declare
  l_id child_table.id%type;
begin
  -- If row(s) with such an ID exists, L_ID will be set to that value. 
  -- In that case, don't do anything
  select m.id
    into l_id
    from child_table m
    where m.id = :P1_ITEM1
      and rownum = 1;

  -- The above query returned something; don't do anything
  null;

exception
  when no_data_found then
    -- The above query didn't return anything, so - delete a row
    delete from child_table where id = :P1_ID;
end;

Теперь это можно / можно / нужно изменить, в зависимости от того, что у вас действительно есть; это просто идея , на что смотреть.

Еще один вариант - установить ограничение внешнего ключа равным on delete cascade, что означает, что удаление основной записи автоматически удаляет ее подробные записи. При этом вы не будете беспокоиться о таких проблемах, и ваш второй процесс будет таким же простым, как

delete from child_table where id = :P1_ID;

(если, конечно, вы не столкнетесь с ошибкой другого типа).


Если вы хотите позволить пользователям решать, хотят ли они удалять строки или нет, измените действие кнопки на «Перенаправить на URL» (в настоящее время это «Отправить», я полагаю). Целевой URL будет примерно таким (предположим, что имя кнопки P1_START_PROCESSES):

javascript:if(confirm('Are you sure you want to delete all rows related to this document?')){doSubmit('P1_START_PROCESSES');}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...