Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2016.07.24;
Скачать: [xml.tar.bz2];

Вниз

Каскадное обновление связных таблиц 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.53 MB
Время: 0.005 c
15-1445020595
K-1000
2015-10-16 21:36
2016.07.24
Direct3D в Delphi


2-1413238792
Германн
2014-10-14 02:19
2016.07.24
Где кликнули правой кнопкой мыши вызывая попап меню?


15-1441385083
Rouse_
2015-09-04 19:44
2016.07.24
Пятничная задача от Розыча


15-1441281618
Landon
2015-09-03 15:00
2016.07.24
Крах приложения внутри FinalizeUnits


15-1444580103
DayGaykin
2015-10-11 19:15
2016.07.24
Удивительный QuickSort





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский