Страница 1 из 1

Правильно ли я программирую?

Добавлено: 2011-12-03 20:58:26
raulr
Здравствуйте!! Пожалуйста, Не проявите ленивость, Обратите внимание!!!

У меня есть пакет RASUL_PKG, которого я сейчась опишу:

Код: Выделить всё

 CREATE OR REPLACE PACKAGE ADBOLNICA.rasul_pkg is 
 procedure set_initial_state; 
 procedure save_id_p (uch number, id number); 
 procedure calc_vrem_preb; 
 cnt number := 0 ; 
 uch_in number; 
 end;
Тело пакета:

Код: Выделить всё

 CREATE OR REPLACE PACKAGE BODY ADBOLNICA.rasul_pkg is 
 type istoria_table is table of number index by pls_integer; 
 id_patient istoria_table; 
 empty istoria_table; 

 procedure set_initial_state is 
 begin 
 cnt:=cnt+1; 
 if (cnt=1) then 
 id_patient := empty; 
 end if; 
 end; 

 procedure save_id_p (uch number, id number) is 
 begin 
 id_patient(uch):=id; 
 end; 

 procedure calc_vrem_preb is 
 --declare 

 date_v date; 
 date_p date; 
 begin 
 if cnt=1 then 
 uch_in := id_patient.first; 
 end if; 
 while uch_in is not null loop 
 select date_vipes into date_v from istoria where uch_nom = uch_in and id_p = id_patient(uch_in); 
 select date_post into date_p from istoria where uch_nom = uch_in and id_p = id_patient(uch_in); 
 if (cnt<=2) then 
 if (date_v is null) then begin cnt:=1; 
 update istoria set vrem_prebivania=0 where uch_nom=uch_in; end; 
 else begin cnt:=1; 
 update istoria set vrem_prebivania=trunc(date_v-date_p) where uch_nom=uch_in; end; 
 end if; 
 end if; 
 id_patient.delete(uch_in); 
 uch_in:=id_patient.next(uch_in); 
 end loop; cnt:=0; 

 end; 
 end;
И есть три UPDATE триггера, на таблицу ISTORIA. Таблица имеет такие поля, как UCH_NOM(primary key), ID_P, DATE_POST, DATE_VIPES, VREM_PRIBIVANIE. При обновлении строки этой таблицы, триггеры дожны вызывать процедур в пакете RASUL_PKG, которые в свою очередь организують вычисления значения поля VREM_PRIBIVANIE (VREM_PREBIVANIE=DATE_VIPES-DATE_POST) этой строки. Вот програмный код этих триггер.

Код: Выделить всё

 CREATE OR REPLACE TRIGGER ADBOLNICA.rasul_trg3 
 before update 
 on istoria
 begin
 rasul_pkg.set_initial_state; 
 end; 


 CREATE OR REPLACE TRIGGER ADBOLNICA.rasul_trg4 
 after update on istoria 
 FOR EACH ROW
 begin
 rasul_pkg.save_id_p(:new.uch_nom,:new.id_p); 
 end;


 CREATE OR REPLACE TRIGGER ADBOLNICA.rasul_trg5 
 After update 
 on istoria
 begin
 rasul_pkg.calc_vrem_preb; 
 end;
Для уточнения: Создал я этих трех триггер во избежании ошибки МУТИРУЮЩИИ ТАБЛИЦЫ. А переменную CNT в теле пакета ввел во избежании ошибки рекурсивных вызовов этих триггер (Обратите внимание, в теле пакета есть DML команда Update, который в свою очередь будет вызывать этих триггер заново)

Делаю Апдейт таблицы ISTORIA командой:

Код: Выделить всё

UPDATE istoria SET date_vipes=sysdate where ID_P>=2 and ID_P<=5
Обновляется 4 записей. Но вычеслен значение поля VREM_PRIBIVANIE только у одной строки, у которой значение поля ID_P=2.

Вопрос: Правильно ли програмный код моего пакета??????? Где я ошибся????? ИЛИ что вы посоветуете, чтоб триггеры вычисляли значения поля VREM_PREBIVANIE всех записи, которых я обновлял с помощью командой:

Код: Выделить всё

 UPDATE istoria SET date_vipes=sysdate where ID_P>=2 and ID_P<=5
????????????

Re: Правильно ли я программирую?

Добавлено: 2012-02-26 21:18:19
Alex Keda
язык-то какой?

Re: Правильно ли я программирую?

Добавлено: 2012-02-27 20:25:13
FiL
Alex Keda писал(а):язык-то какой?
SQL судя по всему :)

Re: Правильно ли я программирую?

Добавлено: 2012-02-28 14:02:55
Alex Keda
дык... SQL тоже разный бывает =))

Re: Правильно ли я программирую?

Добавлено: 2012-04-27 13:34:20
Gloft
Очень похоже на Oracle PL/SQL.

Re: Правильно ли я программирую?

Добавлено: 2012-04-27 13:55:56
Gloft
Собственно мысли по вопросу.
Я с Oracle не работал, но в целом думаю загвоздка в использовании триггеров в этой БД.
А именно строковых и операторных триггеров.
http://www.firststeps.ru/sql/oracle/r.php?112
Насколько я понял триггер ADBOLNICA.rasul_trg5 операторный и он срабатывает единожды после оператора (в данном случае UPDATE).
А значение VREM_PREBIVANIE было рассчитано для одной строки, потому что эта срока обрабатывалась последней.
Если же тебе необходимо выполнять триггер для каждой строки то укажи что он строковый, выставив FOR EACH ROW.
В любом случае если триггеры в целом работают так как надо, но не тогда когда надо читай мануалы.

Re: Правильно ли я программирую?

Добавлено: 2012-04-30 8:00:05
ADRE
*troll face*