Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2016.07.24;
Скачать: CL | DM;

Вниз

Каскадное обновление связных таблиц Oracle+Delphi   Найти похожие ветки 

 
Geo   (2011-06-11 16:32) [0]

Я сам никогда не сталкивался с БД, с работой через ADO, новичек. с делфи все обстоит немного лучше.
Проблема в следующем
Код
 //проверка уникальности и не 0 и нашелся в базе и не равен текущему
if  ((Login_Form.QPatient.Locate("id_patient",id_pat_copy,[loCaseInsensitive])) and (id_patient<>id_pat_copy))  then
  begin
    ShowMessage("Пациент с таким кодом уже существует");
    exit;
  end;

     begin
         if (id_patient=StrToInt(EIdPat.Text)) then
           begin

             ind_copy:=true  //создать нового пациента;
           end
         else   id_patient:=StrToInt(EIdPat.Text);

         with Login_form.QPatient do
          begin
             if ind_copy then
             begin
               Locate("id_patient",id_pat_copy,[loCaseInsensitive]);
               Edit;
             end
             else  Append;

             FieldValues["id_patient"]:=id_patient;
             FieldValues["id_plot"]:=id_plot;
             FieldValues["id_doctor"]:=id_doctor;
             FieldValues["id_policlinic"]:=id_policlinic;
             FieldValues["id_speciality"]:=id_speciality;
             FieldValues["id_street_reg"]:=id_street_reg;
             FieldValues["id_street_home"]:=id_street_home;
             FieldValues["id_ed_inst"]:=id_ed_inst;
             FieldValues["name"]:=Pname;
             FieldValues["surname"]:=surname;
             FieldValues["patronymic"]:=patronymic;
             FieldValues["DOB"]:=DOB;
             FieldValues["insurance_org"]:=insurance_org;
             FieldValues["insurance_num"]:=insurance_num;
             FieldValues["house_reg"]:=house_reg;
             FieldValues["house_home"]:=house_home;
             FieldValues["father"]:=father;
             FieldValues["mother"]:=mother;
             FieldValues["sisters"]:=sisters;
             FieldValues["brothers"]:=brothers;
             FieldValues["SNILS"]:=SNILS;
             if num_card <>"" then
             FieldValues["num_card"]:=num_card;
             FieldValues["document_type"]:=document_type;
             FieldValues["invalidity"]:=invalidity;
             FieldValues["dipans_uch"]:=dipans_uch;
             Post;
           end;

            ////*******************************start******************************
              //Diary-каскадное обновление
             with Login_form.QPatDiary do
                 begin
                    Sql.Clear;
                    Sql.Add("Select * from diary_survey where id_patient="+IntToStr(id_pat_old));
                    Open;
                    if FieldValues["id_diary"]<>null then
                        begin

                           First;
                           Edit;
                           while not EOF  do//Цикл обновления по всем дневникам пациента
                             begin
                                 Edit;
                                 FieldValues["id_patient"]:=id_patient;
                                 FieldValues["id_plot"]:=id_plot;
                                 FieldValues["id_doctor"]:=id_doctor;
                                 FieldValues["id_policlinic"]:=id_policlinic;
                                 FieldValues["id_speciality"]:=id_speciality;
                                 FieldValues["id_street_reg"]:=id_street_reg;
                                 FieldValues["id_street_home"]:=id_street_home;
                                 FieldValues["id_ed_inst"]:=id_ed_inst;
                                 Post;
                                 Next;
                              end;
                          end;
                 end;
     ///******************************end**********************************

                 // льготы
                 with Login_form.QBenefits do
                 begin
                    Sql.Clear;
                    Sql.Add("Select * from BENEFITS where id_patient="+IntToStr(id_pat_old));
                    Open;
                    if FieldValues["id_benefit"]<>null then
                        begin

                           First;
                           Edit;
                           while not EOF  do//Цикл обновления по всем льготам пациента
                             begin
                                 Edit;
                                 FieldValues["id_patient"]:=id_patient;
                                 FieldValues["id_plot"]:=id_plot;
                                 FieldValues["id_doctor"]:=id_doctor;
                                 FieldValues["id_policlinic"]:=id_policlinic;
                                 FieldValues["id_speciality"]:=id_speciality;
                                 FieldValues["id_street_reg"]:=id_street_reg;
                                 FieldValues["id_street_home"]:=id_street_home;
                                 FieldValues["id_ed_inst"]:=id_ed_inst;
                                 Post;
                                 Next;
                              end;
                          end;
                      SQL.Clear;
                      SQL.Add("SELECT * FROM BENEFITS");
                 end;

               with Login_form.QPatient do
                 begin
                 if not ind_copy then      //если создавалась копия
                     begin
                  //удалям старую запись
                       Locate("id_patient",id_pat_old,[loCaseInsensitive]);
                       Delete;
                      end;
                 end;
     end;

На выделенном Post, если мы не меняем id_patient, но меняем id_plot срабатывает триггер


 
Geo   (2011-06-11 16:33) [1]

DECLARE NUMROWS INTEGER;
BEGIN
 /* ERwin Builtin Trigger */
 /* Patients  Diary_survey on parent update restrict */
 /* ERWIN_RELATION:CHECKSUM="000d657c", PARENT_OWNER="", PARENT_TABLE="Patients"
   CHILD_OWNER="", CHILD_TABLE="Diary_survey"
   P2C_VERB_PHRASE="", C2P_VERB_PHRASE="",
   FK_CONSTRAINT="R_10", FK_COLUMNS="id_patient""id_plot""id_doctor""id_policlinic""id_speciality""
             id_street_reg""id_street_home""id_ed_inst" */
 IF
   /* %JoinPKPK(:%Old,:%New," <> "," OR ") */
   :old.id_patient <> :new.id_patient OR
   :old.id_plot <> :new.id_plot OR
   :old.id_doctor <> :new.id_doctor OR
   :old.id_policlinic <> :new.id_policlinic OR
   :old.id_speciality <> :new.id_speciality OR
   :old.id_street_reg <> :new.id_street_reg OR
   :old.id_street_home <> :new.id_street_home OR
   :old.id_ed_inst <> :new.id_ed_inst
 THEN
   SELECT count(*) INTO NUMROWS
     FROM Diary_survey
     WHERE
       /*  %JoinFKPK(Diary_survey,:%Old," = "," AND") */
       Diary_survey.id_patient = :old.id_patient AND
       Diary_survey.id_plot = :old.id_plot AND
       Diary_survey.id_doctor = :old.id_doctor AND
       Diary_survey.id_policlinic = :old.id_policlinic AND
       Diary_survey.id_speciality = :old.id_speciality AND
       Diary_survey.id_street_reg = :old.id_street_reg AND
       Diary_survey.id_street_home = :old.id_street_home AND
       Diary_survey.id_ed_inst = :old.id_ed_inst;
   IF (NUMROWS > 0)
   THEN
/* ********************************MY COD************            */
 /* UPDATE Diary_survey SET Diary_survey.id_plot=:new.id_plot WHERE Diary_survey.id_patient=:new.id_patient;
/* ********************************END OF MY COD************            */
    raise_application_error(
       -20005,
       "Cannot update Patients because Diary_survey exists."
     );
   END IF;
 END IF;


Тригер сгенерирован Erwin, схема в прикрепленном файле
если я пишу то, что помечено как /* ********************************MY COD************ , то срабатывает другой триггер целостности Diary_survey.

Как лучше поступить в данном случае, сорри за длинный пост, просто выложил, чтобы была видна полная картина

Схема - http://www.imageup.ru/img55/dlya-sql678942.png


 
Loginov Dmitry ©   (2011-06-11 21:26) [2]

Курсовая горит? Или диплом?

Судя по объемам выложенного кода, Вам лень со своими проблемами разбираться. Выделенного Post - не видно. Изображение png - нечитабельное. На что рассчитываете?


 
Geo   (2011-06-11 23:31) [3]

Забыл закрыть тег
     FieldValues["document_type"]:=document_type;
            FieldValues["invalidity"]:=invalidity;
            FieldValues["dipans_uch"]:=dipans_uch;
            Post;
          end;


вот этот, самый первый Post

http://www.imageup.ru/img158/1111679227.png

В большем разрешении


 
Geo   (2011-06-11 23:32) [4]

Да, вы правы, диплом.


 
Loginov Dmitry ©   (2011-06-12 00:00) [5]

Попробуйте сформулировать суть проблемы другими словами. В текущей постановке не понятно, что вам нужно.

Смысл триггера не ясен. Каким образом пользователь может умудриться ввести 2 одинаковые записи, у которых одновременно совпадают 8 полей? Контроль подобных вещей обычно не триггерами реализуется, а ограничениями первичного ключа или уникального индекса.


> /* ********************************MY COD************  
>          */
>  /* UPDATE Diary_survey SET Diary_survey.id_plot=:new.id_plot
> WHERE Diary_survey.id_patient=:new.id_patient;
> /* ********************************END OF MY COD************
>            */


Сомневаюсь, что данное решение приведет к желаемому результату. Этим вы все равно не избежите генерацию ошибки raise_application_error, а возникшая ошибка отменит ваш UPDATE.


 
Loginov Dmitry ©   (2011-06-12 00:00) [6]


> Да, вы правы, диплом.


Защита должно быть завтра?


 
Geo   (2011-06-12 00:05) [7]

Нет)


 
Geo   (2011-06-12 00:11) [8]

Ошибка заключается в следующем.
У текущего id_patient есть связные поля в diary_survey и по-этому тригер (если его отключить, то уже оракл) выдает ошибку, что изменить это поле нельзя.
Тоже самое обстоит и с id_plot, т.к. это поле также есть в diary_survey.
Как бы все это каскадно обновить?

Есть бредовая идея - создать еще "нулевую стоку", значение в связной таблице с текущей строки помять на нулевую, переименовать, вернуть значения на место.

Но по-моему это порнография...


 
Виталий Панасенко(дом)   (2011-06-12 00:43) [9]

А что, у Оракла нету каскадного обновления на уровне БД? бред по моему


 
Geo   (2011-06-12 00:52) [10]

Ну у той схемы, что создал Erwin-только предупреждения об ошибках. точнее ошибки с указанием таблиц.


 
Игорь Шевченко ©   (2011-06-12 11:31) [11]


> А что, у Оракла нету каскадного обновления на уровне БД?
>  


нету, есть только каскадное удаление


 
Виталий Панасенко   (2011-06-12 11:49) [12]


> Игорь Шевченко ©   (12.06.11 11:31) [11]

это стеб или внатуре нету? я просто с Ораклом как-то несталкивался(раза два-три и то на уровне выборки данных)


 
Geo   (2011-06-12 13:03) [13]

В том то и дело, нету ON UPDATE CASCADE, вся задача его сэмулировать.


 
Loginov Dmitry ©   (2011-06-12 17:52) [14]


> В том то и дело, нету ON UPDATE CASCADE, вся задача его
> сэмулировать.


Необходимость в каскадном обновлении чаще всего свидетельствует о неудачной структуре БД. Зачем его эмулировать?


 
Geo   (2011-06-12 18:33) [15]

Вот если на схему -   http://www.imageup.ru/img158/1111679227.png посмотреть, нормально, что ключи дублируются ErWinом дочерним таблицам (например в diary_survey есть id_plot), хотя с таблицей plot она не связана напрямую(только через Patients)


 
Geo   (2011-06-12 18:34) [16]

*? - в смысле это было не утверждение, а вопрос


 
Игорь Шевченко ©   (2011-06-12 22:35) [17]

Виталий Панасенко   (12.06.11 11:49) [12]

нету, так как незачем


 
Geo   (2011-06-13 00:35) [18]

Если erwin так проектирует автоматически, возможно в этом есть доля здравого смысла? Никто не знает, можно ли в Ервин отключить дублирование по всем дочерним таблицам FK?


 
Виталий Панасенко(дом)   (2011-06-13 10:12) [19]


>  Игорь Шевченко ©   (12.06.11 22:35) [17]

Ну, это типа спор об искусственных и натуральных ключах..:-) Почему-то во многих СУБД ЭТО :-) присутствует. Видимо, не зря...


 
Игорь Шевченко ©   (2011-06-13 20:54) [20]


> Почему-то во многих СУБД ЭТО :-) присутствует. Видимо, не
> зря...


ну вот касательно оракла:

"Primary keys are supposed to be imutable, never changing, constant.  It is an excessively
bad practice to have to update them ever.  If there is a 0.00001% chance you will have to
update a primary key -- then it is not a primary key, its a surrogate key and you need to
find the true primary key (even if you have to make it up via a sequence) "

http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:5773459616034


 
Anatoly Podgoretsky ©   (2011-06-14 08:44) [21]

> Игорь Шевченко  (13.06.2011 20:54:20)  [20]

Оракл всегда стоял особняком.



Страницы: 1 вся ветка

Текущий архив: 2016.07.24;
Скачать: CL | DM;

Наверх




Память: 0.54 MB
Время: 0.014 c
15-1444771802
Юрий
2015-10-14 00:30
2016.07.24
С днем рождения ! 14 октября 2015 среда


2-1413564529
azl
2014-10-17 20:48
2016.07.24
Вызов процедуры OnClick из модуля


15-1442859281
Kerk
2015-09-21 21:14
2016.07.24
АП


2-1416638766
SKIPtr
2014-11-22 09:46
2016.07.24
тип числа со знаком и плавающей запятой


15-1444638709
Subway
2015-10-12 11:31
2016.07.24
Математическая задача "Проехать все станции метро"