Форум: "Базы";
Текущий архив: 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.006 c