Форма Oracle FRM-40735: триггер ON-ERROR вызвал необработанное исключение ORA-06502

У меня есть триггер таблицы, как показано ниже:

CREATE OR REPLACE TRIGGER PAT_BUR_DOB_TRG
 BEFORE UPDATE OF DOB
 ON PAT
 REFERENCING OLD AS OLD NEW AS NEW
 FOR EACH ROW
-- PL/SQL Block
begin
  tgln_sys_error_pkg.compare_dates(trunc(add_months(:new.dob, -12)),
                                   trunc(tgln_sys_error_pkg.GET_LIST_DATE(:old.pat_id)),
                                   tgln_sys_errnums_pkg.en_retr_waitlist_date);
end;

-------------------------------------- 

У меня есть пакет, который вызывается триггером выше, код пакета выглядит следующим образом:

CREATE OR REPLACE PACKAGE TGLN_SYS_ERROR_PKG AS

/* To compare two dates against each other. */
PROCEDURE COMPARE_DATES
(P_DATE_LOW date
,P_DATE_HIGH date
,P_ERROR_CODE number
);

FUNCTION GET_LIST_DATE
 (P_PAT_ID number)
 RETURN DATE;

END TGLN_SYS_ERROR_PKG;
--------------------------------------   

Тело пакета выглядит следующим образом:

CREATE OR REPLACE PACKAGE BODY TGLN_SYS_ERROR_PKG AS

FUNCTION GET_LIST_DATE(P_PAT_ID number) RETURN DATE IS
  v_ret_date date;
begin

  --select to_date('01-JAN-1980') into p_Date from dual; 

  select max(pwl.eff_date)
    into v_ret_date
    from pat, pat_register pr, pat_register_org_det prod, pat_wait_list pwl
   where pat.pat_id = pr.pat_id
     and pr.patr_id = prod.patr_id
     and prod.prod_id = pwl.prod_id
     and pat.pat_id = P_PAT_ID
     and rownum < 2
     AND pwl.exp_date is null;
  return nvl(v_ret_date, to_date(null));
exception
  when no_data_found then
    return to_date(null);
end GET_LIST_DATE;


PROCEDURE COMPARE_DATES
(P_DATE_LOW date
,P_DATE_HIGH date
,P_ERROR_CODE number
)
IS
begin
if nvl(p_date_low,sysdate-10000)>nvl(p_date_high,sysdate+10000) then
raise_application_error(p_error_code,null);
end if;
end compare_dates;

end TGLN_SYS_ERROR_PKG;
--------------------------------------    
CREATE OR REPLACE PACKAGE TGLN_SYS_ERRNUMS_PKG IS
en_retr_waitlist_date CONSTANT INTEGER := -20088; --Patient waitlist effective dates must not be less than or equal to patient's date of birth minus one year ( DOB - 1 year).     
END TGLN_SYS_ERRNUMS_PKG;
-------------------------------------- 

Каждый раз, когда Oracle Forms обновляет данные DOB, я получаю сообщение об ошибке, как показано ниже:

Форма Oracle FRM-40735: триггер ON-ERROR вызвал необработанное исключение ORA-06502

Но когда я жестко кодирую, как показано ниже:

select to_date('01-JAN-1980') into p_Date from dual; 

вместо этого кода абзаца, как показано ниже, форма работает нормально.

  select max(pwl.eff_date)
    into v_ret_date
    from pat, pat_register pr, pat_register_org_det prod, pat_wait_list pwl
   where pat.pat_id = pr.pat_id
     and pr.patr_id = prod.patr_id
     and prod.prod_id = pwl.prod_id
     and pat.pat_id = P_PAT_ID
     and rownum < 2
     AND pwl.exp_date is null;

Я заменил p_pat_id на реальное значение, выдает ошибку триггера

ORA-04091: table TGLN.PAT is mutating, trigger/function may not see it 
ORA-06512: at "TGLN.TGLN_SYS_ERROR_PKG",
line 130 ORA-06512: at "TGLN.PAT_BUR_DOB_TRG",
line 26 ORA-04088: error during execution of trigger 'TGLN.PAT_BUR_DOB_TRG'
View program sources of error stack?" 

Итак, как исправить ошибку? Я не могу жестко закодировать значения даты


person user1308891    schedule 02.04.2012    source источник
comment
Разве вы не спросили об этом несколько минут/часов назад? Вы могли бы хотя бы сохранить исправления форматирования? Не удаляйте и не публикуйте вопросы повторно, это раздражает (и в конечном итоге приведет к автоматическому бану вопроса, если вы будете делать это слишком часто).   -  person Mat    schedule 02.04.2012
comment
@ user1308891:tgln_sys_error_pkg.compare_dates не соответствует спецификации, это частная процедура. Как вы можете вызвать эту процедуру из триггера. Пожалуйста, исправьте свой код   -  person Gaurav Soni    schedule 03.04.2012
comment
Извините, я новичок в Stackoverflow, не знаю, как его использовать. Пожалуйста!   -  person user1308891    schedule 03.04.2012
comment
Я добавляю в пост спецификацию tgln_sys_error_pkg.compare_dates.   -  person user1308891    schedule 03.04.2012
comment
Не знаю, почему, если я закомментирую код select max(pwl.eff_date)..., триггер сработает, но мне действительно нужен этот оператор выбора.   -  person user1308891    schedule 03.04.2012
comment
Я заменил p_pat_id на реальное значение, выскочила ошибка триггера: ORA-04091: таблица TGLN.PAT мутирует, триггер/функция может ее не увидеть ORA-06512: at TGLN.TGLN_SYS_ERROR_PKG, строка 130 ORA-06512: at TGLN .PAT_BUR_DOB_TRG, строка 26 ORA-04088: ошибка при выполнении триггера 'TGLN.PAT_BUR_DOB_TRG' Просмотреть программные источники стека ошибок?   -  person user1308891    schedule 03.04.2012
comment
если удалить в v_ret_date получить ошибку компиляции. в этом операторе select ожидается предложение into   -  person user1308891    schedule 03.04.2012
comment
скопируйте этот запрос select max(pwl.eff_date)... из функции и попробуйте выполнить его в другом редакторе, без проблем получите правильную дату.   -  person user1308891    schedule 03.04.2012
comment
Когда вы создаете триггер для таблицы, вы не можете изменять/запрашивать эту таблицу до тех пор, пока триггер/функция не завершится.   -  person Gaurav Soni    schedule 03.04.2012
comment
Перекомпилируйте триггер, пакет и все нескомпилированные объекты. и запустите оператор обновления: update pat set pat.dob = to_date('01-JAN-1985'), где pat.pat_id = 21592; получить ту же ошибку, что и до ошибки: ORA-04091: таблица TGLN.PAT видоизменяется, триггер/функция может ее не видеть ORA-06512: в TGLN.TGLN_SYS_ERROR_PKG, строка 130 ORA-06512: в TGLN.PAT_BUR_DOB_TRG, строка 26 ORA -04088: ошибка при выполнении триггера 'TGLN.PAT_BUR_DOB_TRG' Просмотреть программные источники стека ошибок?   -  person user1308891    schedule 03.04.2012


Ответы (1)


Ошибка:

ORA-04091: имя таблицы мутирует, триггер/функция может его не видеть/

Ваша ошибка

trigger error:"ORA-04091: table TGLN.PAT is mutating

Причина:

Оператор выполнил триггер или пользовательскую функцию PL/SQL. Этот триггер/функция пытался изменить или запросить таблицу, которая в настоящее время модифицируется оператором, который запустил триггер/функцию.

Ваше дело

 --you're not supposed to query a table that is currently modified 
 --In you're case its `PAT` table being updated and querying at same time
 select max(pwl.eff_date)
 into v_ret_date
 from pat,  --here you are querying your PAT table,while updating the same table
      pat_register pr, pat_register_org_det prod, pat_wait_list pwl
  where pat.pat_id = pr.pat_id
   and pr.patr_id = prod.patr_id
   and prod.prod_id = pwl.prod_id
   and pat.pat_id = P_PAT_ID
   and rownum < 2
   AND pwl.exp_date is null;

Действие:

Возможные варианты устранения этой ошибки Oracle: Перепишите триггер/функцию, чтобы она не пыталась modify/query выполнить PAT указанную таблицу.

Справочник

person Gaurav Soni    schedule 02.04.2012
comment
Спасибо Гаурав!!! Я изменю оператор select завтра утром, когда буду в офисе, и сообщу вам результат. - person user1308891; 03.04.2012