2016-01-10 2 views
0

Я новичок в оракула, я занимаюсь разработкой системы управления больницы, у меня есть эта таблица для хранения пациентов:Ошибка SQL: ORA-04091: таблица мутирует при обновлении триггером

create table patients(
p_id number not null primary key, 
p_fullname full_name_ty, 
p_gender char, 
de_no number, 
p_entry date , 
Diagnosis varchar2(25), 

p_exit date, 
constraint pdf foreign key (de_no) references department(dep_no) 
); 

где p_entry является дата, когда пациент въезжает в больницу, я совершил триггер, который вычисляет время пребывания в больнице после перерыва даты (p_exit) для пациента (установка этой даты означает, что пациент покинул больницу), триггер будет просто рассчитать разницу между двумя датами и распечатать ее, вот код запуска:

create or replace 
trigger period_trig before update of p_exit on patients for each row 
DECLARE    
period Number(3); 
enterr DATE; 
exitt DATE; 
BEGIN 
enterr := :old.P_ENTRY; 
exitt:= :NEW.P_EXIT; 
Period :=exitt-enterr; 
DBMS_OUTPUT.PUT_LINE('Duration:'||period); 
update patients SET RESIDENCY= Period where P_ID = :old.P_ID; 
end period_trig 

положить, когда я проверить триггер и использовать оператор обновления, как это:

update patients set p_exit = to_date('01/02/2001','dd/mm/yyyy') where p_id = 2; 

и запустить его я получаю эту ошибку:

Error starting at line 1 in command: 
update patients set p_exit = to_date('01/02/2001','dd/mm/yyyy') where p_id = 2 
Error report: 
SQL Error: ORA-04091: table SEM.PATIENTS is mutating, trigger/function may not see it 
ORA-06512: at "SEM.UPDATEPAT", line 5 
ORA-06512: at "SEM.PERIOD_TRIG", line 10 
ORA-04088: error during execution of trigger 'SEM.PERIOD_TRIG' 
04091. 00000 - "table %s.%s is mutating, trigger/function may not see it" 
*Cause: A trigger (or a user defined plsql function that is referenced in 
      this statement) attempted to look at (or modify) a table that was 
      in the middle of being modified by the statement which fired it. 
*Action: Rewrite the trigger (or function) so it does not read that table. 
Error starting at line 1 in command: 
update patients set p_exit = to_date('01/02/2001','dd/mm/yyyy') where p_id = 2 
Error report: 
SQL Error: ORA-04091: table SEM.PATIENTS is mutating, trigger/function may not see it 
ORA-06512: at "SEM.PERIOD_TRIG", line 11 
ORA-04088: error during execution of trigger 'SEM.PERIOD_TRIG' 
04091. 00000 - "table %s.%s is mutating, trigger/function may not see it" 
*Cause: A trigger (or a user defined plsql function that is referenced in 
      this statement) attempted to look at (or modify) a table that was 
      in the middle of being modified by the statement which fired it. 
*Action: Rewrite the trigger (or function) so it does not read that table. 

может кто-нибудь сказать мне, как это исправить? и спасибо большое.

+0

Проблемы здесь вы хотите изменить таблицу в триггере, который уже изменен. В этом случае используйте триггер обновления. Кроме того, рассмотрите вместо этого использование виртуального столбца: http://docs.oracle.com/cd/B28359_01/server.111/b28286/statements_7002.htm#BABIJABG – stee1rat

+0

Почему бы просто не использовать вычисляемый столбец: http: //www.dba- oracle.com/oracle11g/oracle_11g_function_based_columns.htm. Тогда не требуется триггер –

ответ

1

Вы изменяете ту же самую таблицу в триггере, который в настоящее время изменяется. Как ошибка говорит вам:

*Cause: A trigger (or a user defined plsql function that is referenced in 
      this statement) attempted to look at (or modify) a table that was 
      in the middle of being modified by the statement which fired it. 
*Action: Rewrite the trigger (or function) so it does not read that table. 

Там фактически нет необходимости снова обновить таблицу, вы можете просто использовать виртуальный столбец прямо на столе, что делает весь триггер излишним:

CREATE TABLE patients(
    p_id NUMBER NOT NULL PRIMARY KEY, 
    p_fullname VARCHAR2(255), 
    p_gender CHAR(1), 
    de_no NUMBER, 
    p_entry DATE, 
    Diagnosis VARCHAR2(25), 
    p_exit DATE, 
    RESIDENCY NUMBER GENERATED ALWAYS AS (p_exit-p_entry) 
); 


insert into patients (p_id, p_fullname, p_gender, de_no, p_entry, diagnosis) values (1, 'GVENZL', 'M', 1234, SYSDATE-1, 'healthy'); 
commit; 

select p_fullname, residency from patients; 

update patients set p_exit = sysdate; 
commit; 

select p_fullname, residency from patients; 

 Смежные вопросы

  • Нет связанных вопросов^_^