Author Topic: Помогите с БД..................На Inter BAse  (Read 12628 times)

0 Members and 1 Guest are viewing this topic.

Offline Дмитрий Жданов

  • Newbie
  • *
  • Posts: 18
  • Karma: +0/-0
Есть две таблицы - Patient и Osmotr. Таблица Osmotr связанна с таблицей Patient Внешним ключом по полю Pat_ID. В табл. Пациент оно является первичным ключом,  значения в это поле вносятся с помощью генератора...........
Нужно, чтобы при занесении пациента в Patient (Pat_ID) автоматически это же значение заносилось в поле Pat_ID таблицы Osmotr. Здесь это поле не является первичным ключом........На нем просто установленно значение  Not Null.
Я эти таблицы соединил с помощью внешнего ключа, но желаемого эффекта не получил..............В тупик такой зашел.......В литературе найти ничего не могу......Там просто пишется, что после создания внешнего ключа все значения родительской таблицы будут автоматом присваиваться дочерней (тому же полю, что и в родительской)....Может надо что то в самом приложении настраивать, чтобы значения автоматом полю присваивались?? Приложение, кстати, в Delphi разрабатывается............
Внешний ключ в скрипте после создания всех таблиц прописывал:

ALTER TABLE Osmotr
ADD CONSTRAINT Pat_OSmotr FOREIGN KEY(Pat_ID) REFERENCES
Patient(Pat_ID)
On Delete Cascade
On Update Cascade;

Подскажите, что нужно сделать?? Буду вам очень признателен.....................  

Offline sie

  • Full Member
  • ***
  • Posts: 108
  • Karma: +0/-0
Помогите с БД..................На Inter BAse
« Reply #1 on: April 07, 2007, 15:58:07 »
Quote from: Дмитрий Жданов
Там просто пишется, что после создания внешнего ключа все значения родительской таблицы будут автоматом присваиваться дочерней (тому же полю, что и в родительской)....
Невнимательно, видимо, читали. Вот и заблудились.
В вашем же скрипте написано:
Quote from: Дмитрий Жданов
On Delete Cascade
On Update Cascade;
что означает реакцию СУБД при удалении и обновлении, но никак ни при добавлении записей.

Вариант 1: Примитивный.
Сразу после добавления записи в таблицу Patient выполнить запрос
Code: [Select]
SELECT MAX(Pat_ID) AS LastPatID FROM Patientдалее значение LastPatID использовать для вставки записей в дочернюю таблицу.

Вариант 2: Чуть более продвинутый.
Использовать хранимую процедуру (с именем, например, GetPatIDGen) вместо запроса.
Code: [Select]
CREATE GENERATOR PatIDGen;
SET GENERATOR PatIDGen TO 0;

SET TERM ^;

CREATE TRIGGER PatientBeforeInsert FOR Patient
ACTIVE BEFORE INSERT
AS
BEGIN
 NEW.Pat_ID = GEN_ID(PatIDGen, 1);
END ^

CREATE PROCEDURE GetPatIDGen
RETURNS (CurrentPatID INTEGER)
AS
BEGIN
 CurrentPatID = GEN_ID(PatIDGen, 0);
END ^

SET TERM; ^
Без соответствующей доработки оба варианта исключают одновременную работу нескольких пользователей с таблицами. Сами подумайте почему...

Offline Дмитрий Жданов

  • Newbie
  • *
  • Posts: 18
  • Karma: +0/-0
Помогите с БД..................На Inter BAse
« Reply #2 on: April 07, 2007, 18:40:18 »
Спасибо большое    Мне и не нужна одновременная работа нескольких пользователей с таблицей.....Максимум один человек будет БД использовать............Работа нескольких пользователей с базой в ооочень далёкой перспективе   Рабочее место одного врача-специалиста будет.........О полной автоматизации больнички ещё даже и речи не велось)


Вариант 1: Примитивный.

Сразу после добавления записи в таблицу Patient выполнить запрос
Code: [Select]
SELECT MAX(Pat_ID) AS LastPatID FROM Patientдалее значение LastPatID использовать для вставки записей в дочернюю таблицу.

Т. е. здесь, если правильно понял, потом надо будет написать запрос на вставку значения LastPatID в дочернюю таблицу???

Генераторы я сделал.......все отлично работает......Только здесь ступор какой то    


Offline sie

  • Full Member
  • ***
  • Posts: 108
  • Karma: +0/-0
Помогите с БД..................На Inter BAse
« Reply #3 on: April 07, 2007, 18:56:15 »
Quote from: Дмитрий Жданов
Т. е. здесь, если правильно понял, потом надо будет написать запрос на вставку значения LastPatID в дочернюю таблицу???
Да. К примеру:
Code: [Select]
SourceQuery.SQL.Clear;
SourceQuery.SQL.Append('SELECT MAX(Pat_ID) AS LastPatID');
SourceQuery.SQL.Append('FROM Patient');
...
LastPatID := SourceQuery.FieldByName('LastPatID').AsInteger;
...
YourQuery.SQL.Clear;
YourQuery.SQL.Append('INSERT INTO Osmotr (..., Pat_ID, ...)');
YourQuery.SQL.Append('VALUES (..., :Pat_ID, ...)');
YourQuery.ParamByName('Pat_ID').AsInteger := LastPatID;
....

Code: [Select]
SourceQuery.SQL.Clear;
SourceQuery.SQL.Append('SELECT MAX(Pat_ID) AS LastPatID');
SourceQuery.SQL.Append('FROM Patient');
...
LastPatID := SourceQuery.FieldByName('LastPatID').AsInteger;
...
YourQuery.SQL.Clear;
YourQuery.SQL.Append('INSERT INTO Osmotr (..., Pat_ID, ...)');
YourQuery.SQL.Append('VALUES (..., ' + IntToStr(LastPatID) + ', ...)');
...

Code: [Select]
YourQuery.SQL.Clear;
YourQuery.SQL.Append('INSERT INTO Osmotr (..., Pat_ID, ...)');
YourQuery.SQL.Append('SELECT CAST(... AS ...), ..., MAX(Pat_ID), CAST(... AS ...), ...)');
YourQuery.SQL.Append('FROM Patient');
...
« Last Edit: April 07, 2007, 18:58:22 by sie »

Offline Дмитрий Жданов

  • Newbie
  • *
  • Posts: 18
  • Karma: +0/-0
Помогите с БД..................На Inter BAse
« Reply #4 on: April 08, 2007, 19:56:43 »
Спасибо))  Но он почему то в этом месте ошибку выдает:
Code: [Select]
...
LastPatID := SourceQuery.FieldByName('LastPatID').AsInteger;
...

"SourseQuery:Field 'LastPatID' not found"

Offline Дмитрий Жданов

  • Newbie
  • *
  • Posts: 18
  • Karma: +0/-0
Помогите с БД..................На Inter BAse
« Reply #5 on: April 08, 2007, 22:45:00 »
Догадался как убрать ошибку.........Но поля все равно не заполняются  

Почему то переменной LastPatId значение не присваивается........Сам запрос правильно выполняется

Offline sie

  • Full Member
  • ***
  • Posts: 108
  • Karma: +0/-0
Помогите с БД..................На Inter BAse
« Reply #6 on: April 08, 2007, 23:05:31 »
Quote from: Дмитрий Жданов
Почему то переменной LastPatId значение не присваивается...
Исходники в студию! Телепаты в отпуске...

Offline Дмитрий Жданов

  • Newbie
  • *
  • Posts: 18
  • Karma: +0/-0
Помогите с БД..................На Inter BAse
« Reply #7 on: April 08, 2007, 23:16:57 »
Code: [Select]
Modul.SourseQuery.SQL.Clear;
Modul.SourseQuery.SQL.Append('SELECT MAX(Pat_ID) AS LastPatID');
Modul.SourseQuery.SQL.Append('FROM Patient');
LastPatID:=Modul.SourseQuery.FieldByName('LastPatID').AsInteger;
Modul.IBOsmotr.SQL.Clear;
Modul.IBOsmotr.SQL.Append('Insert into Osmotr (Pat_ID,Date_ID,Doc_ID,Zhaloby,CHDD,CHSS,Weight,Height,Recom)');
Modul.IBOsmotr.SQL.Append('Values (:Pat_ID,:Date_ID,:Doc_ID,:Zhaloby,:CHDD,:CHSS,:Weight,:Height,:Recom)');
Modul.IBOsmotr.ParamByName('Pat_ID').AsInteger:=LastPatID;


Вот.........Переменной LAstPatID значение не присваивается в строчке:

Code: [Select]
LastPatID:=Modul.SourseQuery.FieldByName('LastPatID').AsInteger;

Поэтому значение и не заносится. Нуль постоянно считывает. До неё все рабочее. В IBConsole проверил...правильно считает.

Offline demiurg

  • Hero Member
  • *****
  • Posts: 1014
  • Karma: +0/-0
    • http://larin.tomsk.ru
Помогите с БД..................На Inter BAse
« Reply #8 on: April 09, 2007, 01:47:26 »
Quote from: Дмитрий Жданов
Code: [Select]
Modul.SourseQuery.SQL.Clear;
Modul.SourseQuery.SQL.Append('SELECT MAX(Pat_ID) AS LastPatID');
Modul.SourseQuery.SQL.Append('FROM Patient');
LastPatID:=Modul.SourseQuery.FieldByName('LastPatID').AsInteger;
Modul.IBOsmotr.SQL.Clear;
Modul.IBOsmotr.SQL.Append('Insert into Osmotr (Pat_ID,Date_ID,Doc_ID,Zhaloby,CHDD,CHSS,Weight,Height,Recom)');
Modul.IBOsmotr.SQL.Append('Values (:Pat_ID,:Date_ID,:Doc_ID,:Zhaloby,:CHDD,:CHSS,:Weight,:Height,:Recom)');
Modul.IBOsmotr.ParamByName('Pat_ID').AsInteger:=LastPatID;
Вот.........Переменной LAstPatID значение не присваивается в строчке:

Code: [Select]
LastPatID:=Modul.SourseQuery.FieldByName('LastPatID').AsInteger;

Поэтому значение и не заносится. Нуль постоянно считывает. До неё все рабочее. В IBConsole проверил...правильно считает.
Ну так, а Modul.SourseQuery.Open кто будет делать после Modul.SourseQuery.SQL.Append('FROM Patient') ?
А после Modul.IBOsmotr.ParamByName нужен Modul.IBOsmotr.ExecSQL
И на мой взгляд, все это очень не правильно и не аккуратно.

Offline Дмитрий Жданов

  • Newbie
  • *
  • Posts: 18
  • Karma: +0/-0
Помогите с БД..................На Inter BAse
« Reply #9 on: April 09, 2007, 18:12:07 »
А как правильней написать??)

Offline Дмитрий Жданов

  • Newbie
  • *
  • Posts: 18
  • Karma: +0/-0
Помогите с БД..................На Inter BAse
« Reply #10 on: April 09, 2007, 19:03:06 »
Я просто раньше на BDE только все делал........Здесь разобраться никак не могу
« Last Edit: April 09, 2007, 19:45:39 by Дмитрий Жданов »

Offline demiurg

  • Hero Member
  • *****
  • Posts: 1014
  • Karma: +0/-0
    • http://larin.tomsk.ru
Помогите с БД..................На Inter BAse
« Reply #11 on: April 10, 2007, 10:05:21 »
Quote from: Дмитрий Жданов
Я просто раньше на BDE только все делал........Здесь разобраться никак не могу
BDE это всего лишь Borland Database Engine набор драйверов для работы с БД причем разными.
Обсуждать недостатки не будем, скажу лишь, что если Вы используете компоненты которые "напрямую" работают с gds.dll (или как она там называется) никакой разницы нет.
Я не понимаю зачем "в ручную" делать insert'ы в базу.
Кроме того, какой смысл городить клиент-серверное приложение, если Вы сразу же архитектурно ограничиваетесь работой одного пользователя, если Вам понадобится работа двух пользователей переделать будет очень сложно.
На мой взгляд проще использовать TDB компоненты для заполнения полей записи и использовать транзакции для того чтобы пользователь мог откатить случайно внесенные изменения.

Offline Дмитрий Жданов

  • Newbie
  • *
  • Posts: 18
  • Karma: +0/-0
Помогите с БД..................На Inter BAse
« Reply #12 on: May 02, 2007, 20:20:43 »
Я совсем о другому сделал..............
Завел переменную(PatID), которой присвоил порядковый номер пациента (Pat_ID).
номер соответствует выбранной записи в таблице Patient:

PatID:= Modul.DatPat.FieldByName('Pat_ID').AsInteger;

Затем для занесения в таблицу Osmotr  в поле Pat_ID просто присвоил эту переменную определенной строке в таблице.Это осуществляется при вставке новой записи.

Offline CRonaldo

  • Jr. Member
  • **
  • Posts: 50
  • Karma: +0/-0
Помогите с БД..................На Inter BAse
« Reply #13 on: June 13, 2007, 22:31:19 »
А не проще ли всё это через DataSet организовать? Или я чего-то не догоняю?

Offline Дмитрий Жданов

  • Newbie
  • *
  • Posts: 18
  • Karma: +0/-0
Помогите с БД..................На Inter BAse
« Reply #14 on: June 25, 2007, 19:16:42 »
Я так и сделал...............Там проблема с генераторами тоже была...............Надо было у ключевого столбика (В котором значение генератора сохраняется) свойство Requared (неправильно написал по моему   в значение FAlse перевести)

Quote from: Дмитрий Жданов
Я так и сделал...............Там проблема с генераторами тоже была...............Надо было у ключевого столбика (В котором значение генератора сохраняется) свойство Requared (неправильно написал по моему   в значение FAlse перевести)

А запись только так получилось сделать.......................Даже если ссылочную целостность в скрипте при создании БД прописывать (по идее все новые значения из родительского столбца одной таблицы должны записываться в дочерние столбцы других таблиц)

Offline CRonaldo

  • Jr. Member
  • **
  • Posts: 50
  • Karma: +0/-0
Помогите с БД..................На Inter BAse
« Reply #15 on: June 26, 2007, 02:56:18 »
Quote from: Дмитрий Жданов
Я так и сделал...............Там проблема с генераторами тоже была...............Надо было у ключевого столбика (В котором значение генератора сохраняется) свойство Requared (неправильно написал по моему   в значение FAlse перевести)
Не понял что там цитировалось но...
Вообще-то этот самый так называемый столбик ставится Required в False когда значение генератора будет изменяться с помощью (допустим триггеров) базы, но я бы посоветовал DataSet подключить к генератору,  что бы он мог обращаться к генератору и получать из него значение до вставки в базу. Тогда можно и нужно свойство Required этого поля поставить в True.
PS. Я кстати тоже базу для больницы делаю.

Offline Дмитрий Жданов

  • Newbie
  • *
  • Posts: 18
  • Karma: +0/-0
Помогите с БД..................На Inter BAse
« Reply #16 on: June 29, 2007, 21:53:06 »
Quote from: CRonaldo
Не понял что там цитировалось но...
Вообще-то этот самый так называемый столбик ставится Required в False когда значение генератора будет изменяться с помощью (допустим триггеров) базы, но я бы посоветовал DataSet подключить к генератору,  что бы он мог обращаться к генератору и получать из него значение до вставки в базу. Тогда можно и нужно свойство Required этого поля поставить в True.
PS. Я кстати тоже базу для больницы делаю.



Я триггеры как раз и использую)  Сначала генератор к нему создаю, потом триггер для него, чтобы значения из него брать.......
Не работало просто с этим свойством ничего..............Хоть убей) Пока не отрубишь - программа ругаеттся......Хочешь - потестируй программку........Начальную её версию)

http://freelance.tomsk.ru/up.php?id=3241

А для какой больницы??)
« Last Edit: June 29, 2007, 21:55:53 by Дмитрий Жданов »

Offline CRonaldo

  • Jr. Member
  • **
  • Posts: 50
  • Karma: +0/-0
Помогите с БД..................На Inter BAse
« Reply #17 on: June 30, 2007, 03:50:35 »
Quote from: Дмитрий Жданов
А для какой больницы??)
Секрет
У меня база сетевая, таблиц около 40 включая справочные.
Я триггерами сначала начал делать обработку инфы, а потом понял что если интерфейс на Дельфи делать, то проще в Дельфи это и реализовать. Поэтому триггера все поотключал нафиг, даже которые генераторы переключают.
Ты же через DataSet делал я полагаю!? или SQL везде писал? Как я тут заметил.
Ты анализы (допустим биохимию) к истории цеплял или к пациенту?
Кстати о меню, у тебя там не очень удобно сделано когда сверху меню выбираешь, что бы оно разворачивалось, а то так мне кажется не для всех привычно. Либо я думаю их на кнопки вынести, либо в какие нибудь группы запихать, лишь бы меню разворачивалось.
Ещё где МРТ когда Чекбоксы ставишь, пустые он у тебя не берёт, может так и надо. Хотя это же бэта версия  
PS. Понравилась цветовая гамма где анализы, возможно украду
« Last Edit: June 30, 2007, 04:33:57 by CRonaldo »

Offline Дмитрий Жданов

  • Newbie
  • *
  • Posts: 18
  • Karma: +0/-0
Помогите с БД..................На Inter BAse
« Reply #18 on: June 30, 2007, 17:22:30 »
Quote from: CRonaldo
Секрет
У меня база сетевая, таблиц около 40 включая справочные.
Я триггерами сначала начал делать обработку инфы, а потом понял что если интерфейс на Дельфи делать, то проще в Дельфи это и реализовать. Поэтому триггера все поотключал нафиг, даже которые генераторы переключают.
Ты же через DataSet делал я полагаю!? или SQL везде писал? Как я тут заметил.
Ты анализы (допустим биохимию) к истории цеплял или к пациенту?
Кстати о меню, у тебя там не очень удобно сделано когда сверху меню выбираешь, что бы оно разворачивалось, а то так мне кажется не для всех привычно. Либо я думаю их на кнопки вынести, либо в какие нибудь группы запихать, лишь бы меню разворачивалось.
Ещё где МРТ когда Чекбоксы ставишь, пустые он у тебя не берёт, может так и надо. Хотя это же бэта версия  
PS. Понравилась цветовая гамма где анализы, возможно украду


Сохранение\удаление\изменение и вставка через DataSet прорабатываются..............Только процедуру при нажатии кнопки нужную вызвать надо.   Сортировка пациентов, поиск - на SQL написаны.........Для каждого анализа своя таблица.......Там по сути каждое окошко соответствует таблице......Кроме небольших (течение болезни. например). Так проще, чем все данные в одну таблицу запихивать.
Поначалу всё кнопками было - потом придрались к этому и вверх вынести пришлось......Мне они тоже больше нравятся....А то, что Чебоксары пустые Так и задумано........Если пустые, то они заполнены - полные - галочка в них появляется) Вот так

А плагиатом нехорошо заниматься
« Last Edit: June 30, 2007, 17:24:17 by Дмитрий Жданов »

Offline CRonaldo

  • Jr. Member
  • **
  • Posts: 50
  • Karma: +0/-0
Помогите с БД..................На Inter BAse
« Reply #19 on: June 30, 2007, 22:39:33 »
Т.е. процедуры у тебя в интербэйзе храняться, а из Дельфи ты их вызываешь?
А у меня всё в Дэльфи обрабатывается, там возможностей больше, поэтому и решил там их делать. Твой вариант наверное шустрее должен работать, хотя думаю разницы почти нет.