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

MySQL/PostgreSQL/SQLite/Oracle/M$SQL/....

Модератор: terminus

Правила форума
Убедительная просьба юзать теги [code] при оформлении листингов.
Сообщения не оформленные должным образом имеют все шансы быть незамеченными.
raulr
проходил мимо
Сообщения: 5
Зарегистрирован: 2011-10-05 6:54:25

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

Непрочитанное сообщение raulr » 2011-12-03 20:58:26

Здравствуйте!! Пожалуйста, Не проявите ленивость, Обратите внимание!!!

У меня есть пакет 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
????????????

Хостинговая компания Host-Food.ru
Хостинг HostFood.ru
 

Услуги хостинговой компании Host-Food.ru

Хостинг HostFood.ru

Тарифы на хостинг в России, от 12 рублей: https://www.host-food.ru/tariffs/hosting/
Тарифы на виртуальные сервера (VPS/VDS/KVM) в РФ, от 189 руб.: https://www.host-food.ru/tariffs/virtualny-server-vps/
Выделенные сервера, Россия, Москва, от 2000 рублей (HP Proliant G5, Intel Xeon E5430 (2.66GHz, Quad-Core, 12Mb), 8Gb RAM, 2x300Gb SAS HDD, P400i, 512Mb, BBU):
https://www.host-food.ru/tariffs/vydelennyi-server-ds/
Недорогие домены в популярных зонах: https://www.host-food.ru/domains/

Аватара пользователя
Alex Keda
стреляли...
Сообщения: 35418
Зарегистрирован: 2004-10-18 14:25:19
Откуда: Made in USSR
Контактная информация:

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

Непрочитанное сообщение Alex Keda » 2012-02-26 21:18:19

язык-то какой?
Убей их всех! Бог потом рассортирует...

FiL
ст. лейтенант
Сообщения: 1374
Зарегистрирован: 2010-02-05 0:21:40

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

Непрочитанное сообщение FiL » 2012-02-27 20:25:13

Alex Keda писал(а):язык-то какой?
SQL судя по всему :)

Аватара пользователя
Alex Keda
стреляли...
Сообщения: 35418
Зарегистрирован: 2004-10-18 14:25:19
Откуда: Made in USSR
Контактная информация:

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

Непрочитанное сообщение Alex Keda » 2012-02-28 14:02:55

дык... SQL тоже разный бывает =))
Убей их всех! Бог потом рассортирует...

Gloft
лейтенант
Сообщения: 645
Зарегистрирован: 2008-03-09 11:32:12
Откуда: Москва

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

Непрочитанное сообщение Gloft » 2012-04-27 13:34:20

Очень похоже на Oracle PL/SQL.

Gloft
лейтенант
Сообщения: 645
Зарегистрирован: 2008-03-09 11:32:12
Откуда: Москва

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

Непрочитанное сообщение Gloft » 2012-04-27 13:55:56

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

Аватара пользователя
ADRE
майор
Сообщения: 2641
Зарегистрирован: 2007-07-26 8:53:49
Контактная информация:

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

Непрочитанное сообщение ADRE » 2012-04-30 8:00:05

*troll face*
//del