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

Вниз

IBDataSet, Master-Detail и Insert   Найти похожие ветки 

 
grav   (2008-05-20 09:45) [0]

Есть три связанных IBDataSet.
MasterDS-DetailDS1-DetailDS2. Соответственно Предприятие-Здания-данные по зданию. Предприятий много, у каждого прежприятия зданий много, у каждого здания одна запись с данными (площадь, стоимость и т.д.).
Список предприятий не меняется. Здания могут добавляться, редактироваться и удаляться. Данные по зданию могут редактироваться, удаляться вместе со зданием и добавляться вместе со зданием.
Встака записей в таблицу здания проходит без проблем. Вставка в тблицу с данными по зданию проходит без ошибок, но в таблицу не попадают. Почему? Как отследить что не так, если никаких ошибок не выводится?


 
Anatoly Podgoretsky ©   (2008-05-20 09:53) [1]

Если на здание одна запись с данными, то третья таблица не нужна и данные должны быть перенесены во вторую таблицу.
Мастер-детайл связи - это один ко многим, а не один к одному.


 
Sergey13 ©   (2008-05-20 09:57) [2]

> [0] grav   (20.05.08 09:45)
> Как отследить что не так, если никаких ошибок не выводится?

Как обычно - ковыряться в коде и в пропертях компонентов. Как еще то?


 
grav   (2008-05-20 10:02) [3]


> Anatoly Podgoretsky ©   (20.05.08 09:53) [1]

Дело в том, что база сложнее. У каждого здания есть еще объекты.
Получается так: Предприятие-Здания-Объекты. Но...
У Предприятия, здания и объекта есть свои данные (площадь, стоимость и т.д.). Вот эти данные я и вынес в отдельную таблицу. Предполагается, что предприятий будет около 6 тыс., зданий от нескольких единиц до нескольких сот, объектов тысячи, таблица с данными будет содержать под миллион записей.


 
Sergey13 ©   (2008-05-20 10:08) [4]

> [3] grav   (20.05.08 10:02)

У одного здания или объекта может быть НЕСКОЛЬКО площадей и/или стоимостей?


 
grav   (2008-05-20 10:09) [5]


> Sergey13 ©   (20.05.08 09:57) [2]

Делаю
DetailDS2.Inset;
DetailDS2.FieldByName(ID_ORG).AsInteger:=DetailDS1.FieldByName(ID_ORG).AsInteger ;
DetailDS2.FieldByName(ID_Build).AsInteger:=DetailDS1.FieldByName(ID).AsInteger;
DetailDS2.FieldByName(ID_OBJ).AsInteger:=0;
DetailDS2.Post;

Эти три поля образуют ключ и являются единственными полями, которые не могут быть NULL.
Проверяю DetailDS2.UpdatesPending , изменения есть. Делаю
DetailDS2.ApplyUpdates;
MainForm.StartTr.Commit;
Все проходит без ошибок. Данные в таблице не появляются.

Тоже самое, если делать DetailDS2.Edit;


 
grav   (2008-05-20 10:14) [6]


> Sergey13 ©   (20.05.08 10:08) [4]

Нет, запись по каждому зданию и объекту в таблице с данными одна. Выделил эти данные в отдельную таблицу только из-за того, что поля в таблицах одинаковы (правда не все поля пересекаются, т.е. некоторые поля уникальны для объекта или здания).


 
Sergey13 ©   (2008-05-20 10:17) [7]

> [5] grav   (20.05.08 10:09)
> Эти три поля образуют ключ

Какой ключ? Первичный? А почему не просто ID, как в других (насколько я понял) таблицах.?
Что есть такое ID_OBJ?


 
grav   (2008-05-20 10:17) [8]

Еще вот что.
Все вышеописанное, т.е. Inset и Edit для DetailDS1 работает без проблем.
Есть еще одна свзяка DetailDS1-DetailDS3 (здания-0бъекты), также не работает вставка и редактирование.


 
grav   (2008-05-20 10:17) [9]

Еще вот что.
Все вышеописанное, т.е. Inset и Edit для DetailDS1 работает без проблем.
Есть еще одна свзяка DetailDS1-DetailDS3 (здания-0бъекты), также не работает вставка и редактирование.


 
Sergey13 ©   (2008-05-20 10:21) [10]

> [6] grav   (20.05.08 10:14)

Ты все таки удивительно хреново описываешь свою задачу.
Давай просто структуру таблиц - без своих коментариев (пока не попросят 8-)

Здания и объекты - это в одной таблице?

> что поля в таблицах одинаковы

В каких таблицах?


 
Anatoly Podgoretsky ©   (2008-05-20 10:24) [11]

> grav  (20.05.2008 10:02:03)  [3]

Может ты не договариваешь, говоришь о один к одному, а на самом деле один ко многим.
Реализовывать связь один к одному имеет смысл только по архитектурным ограничениями СУБД


 
Anatoly Podgoretsky ©   (2008-05-20 10:25) [12]

> Sergey13  (20.05.2008 10:08:04)  [4]

Может быть, площадь может измениться, а стоимость и тем более, но это называется история и там как правило еще и связи многие ко многим.


 
ЮЮ ©   (2008-05-20 10:26) [13]

> Выделил эти данные в отдельную таблицу только из-за того,
> что поля в таблицах одинаковы


Главная ошибка первых лет проектирования баз жанных :)

Похожесть атрибутов разных сущностей — не повод порождать синтетическую сущность, ИМХО.

Атрибуты зданий — в таблицу зданий, атрибуты объектов — в таблицу объектов


> зданий от нескольких единиц до нескольких сот, объектов
> тысячи, таблица с данными будет содержать под миллион записей.

Странная арифметика.

данные = здания + объекты = тысячи. Откуда миллионы?


 
grav   (2008-05-20 10:34) [14]


> Sergey13 ©   (20.05.08 10:21) [10]

Имеется три таблицы ORGAN, BUILDING и DATA.
В таблице ORGAN есть ключ с именем ID и поля с кодами организации из справочников.
В таблице BUILDING есть ключ ID и поле ID_ORG (для связи  с таблицей ORGAN).
В таблице DATA есть тройной ключ: ID_ORG, ID_BUILD, ID_OBJ, уникальный, данные поля не могут быть null.
Если в таблице DATA: ID_ORG<>0, а ID_BUILD=ID_OBJ=0 - это означает, что данная запись принадлежит предприятию
Если ID_ORG<>0 и ID_BUILD<>0, а ID_OBJ=0 - запись принадлежит зданию
Если ID_ORG<>0 и ID_BUILD<>0 и ID_OBJ<>0 - запись принадлежит объекту (ID_OBJ из генератора).


 
grav   (2008-05-20 10:40) [15]


> Anatoly Podgoretsky ©   (20.05.08 10:25) [12]

История не нужна, это разовое обследование инфраструктуры.


> ЮЮ ©   (20.05.08 10:26) [13]

Я не писал миллионы, я писал под миллион записей. В каждом предприятии может сотня зданий, в каждом здании сотня объектов. Итого у предприятия м.б. тысяча объектов. 6000 предприятий на 1000 объектов = 6 миллионов. Но я думаю будет около миллиона.


 
ЮЮ ©   (2008-05-20 10:43) [16]

> Если ID_ORG<>0 и ID_BUILD<>0, а ID_OBJ=0 &#151; запись принадлежит

Не смущает, что BUILDING с таким ID может запросто принадлежать другой ORGAN, не той что в ID_ORG?
ID_ORG в таблице здесь соверщенно лишний!!!


 
Sergey13 ©   (2008-05-20 10:46) [17]

> [12] Anatoly Podgoretsky ©   (20.05.08 10:25)
> Может быть, площадь может измениться

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


 
ЮЮ ©   (2008-05-20 10:48) [18]

> (правда не все поля пересекаются, т.е. некоторые поля уникальны
> для объекта или здания).


Даже не экономишь на месте :) Тогда в чем причина?
Настаиваю на ORGANS, BUILDINGS и OBJECTS.

P.S. Имя таблицы организаций диссонируют с именами других таблиц, не замечаешь?


 
Sergey13 ©   (2008-05-20 10:53) [19]

> [14] grav   (20.05.08 10:34)

А может быть здание без объектов?


 
grav   (2008-05-20 10:57) [20]


> ЮЮ ©   (20.05.08 10:43) [16]

Да, красноречив это не про меня :)
Три поля ID_ORG, ID_BUILD и ID_OBJ образуют уникальный ключ. Т.е. знацения 5,0,0 уникально и данные этой записи будут принадлежать организации. Т.е. когда я сделаю select * from DATA where ID_ORG=5 and ID_BUILD=0 and ID_OBJ=0 отберется одна запись.


 
grav   (2008-05-20 10:58) [21]


> Sergey13 ©   (20.05.08 10:53) [19]

Нет. Что то в нем есть, иначе зачем здание?


 
grav   (2008-05-20 11:02) [22]

Вообщем то данные в базу уже заносятся.
Я пытаюсь дописать изменение данных. Мне без проблем это сделать с помощью обычных IBQuery или IBSQL. Но вот захотелось чрез DBGrid"ы и мастер детайл.


 
ЮЮ ©   (2008-05-20 11:08) [23]

> Если в таблице DATA: ID_ORG<>0, а ID_BUILD=ID_OBJ=0 &#151; это
> означает, что данная запись принадлежит предприятию


Ты туда ещё и характеристики предприятия примешал :)


> Да, красноречив это не про меня :)

Я не о том.
Пусть имеем
 ORGAN      BUILDING
 ID         ID  ID_ORG          
 1          1    1
 2          2    2


Если не делать особых телодвищений по обеспецению правильности данных, то в  
DATA запросто может оказаться
ID_ORG ID_BUILD ID_OBJ  
  1       2      222


 
Sergey13 ©   (2008-05-20 11:14) [24]

> [21] grav   (20.05.08 10:58)

Тогда однозначно

> [18] ЮЮ ©   (20.05.08 10:48)
> Настаиваю на ORGANS, BUILDINGS и OBJECTS.


 
ЮЮ ©   (2008-05-20 11:27) [25]

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

организации
SELECT Id FROM Organs
 инфа об организации
 SELECT * FROM DATA WHERE (ID_ORG = :Id) and (ID_BUILD = 0) AND (ID_OBJ = 0)  

 здания организации
 SELKCT Id,  ID_ORG  FROM BUILDING WHERE (ID_ORG = :Id)
   
   инфа о зданиях
   SELECT * FROM DATA WHERE (ID_ORG = :Id_Orп) and (ID_BUILD = :Id) AND (ID_OBJ = 0)  

   объекты хдания
   SELECT * FROM DATA WHERE (ID_ORG = :Id_Orп) and (ID_BUILD = :Id_Bild) AND (ID_OBJ <> 0)
 

З.Ы. detail-запросы сдвинуты относительно master


 
grav   (2008-05-20 11:29) [26]


> ЮЮ ©   (20.05.08 11:08) [23]

Если датасеты свзяаны между собой то такого быть не может вроде бы. Т.к. Если пользователь выбрал предприятие в гриде, то во втором гриде отображаются только здания принадлежащие данному предприятию. Тогда при добавлении в таблицу данных Из DetailDS2 возьмется ID_ORG=1 ID_BUILD=1, других данных в датасете не будет просто.


 
ЮЮ ©   (2008-05-20 11:33) [27]

> Т.к. Если пользователь выбрал предприятие в гриде, то во
> втором гриде отображаются только здания принадлежащие данному
> предприятию.

Гридов у тебя еще нет, а IBExpert у кого-нибудь найдется :)


 
ЮЮ ©   (2008-05-20 11:39) [28]

> Делаю
> DetailDS2.Inset;
> DetailDS2.FieldByName(ID_ORG).AsInteger:=DetailDS1.FieldByName(ID_ORG)
> .AsInteger ;
> DetailDS2.FieldByName(ID_Build).AsInteger:=DetailDS1.FieldByName(ID)
> .AsInteger;
> DetailDS2.FieldByName(ID_OBJ).AsInteger:=0;
> DetailDS2.Post;


в каком методе?
А где пользовательские данные, что он колотил в гриде?

В этом коде втавка пустой строки, соответсиыующкй новой строке в BUILDING.
А как пользователь добавит запись в таблицу BUILDING, если та нечего отобрвжать в гриде?


 
grav   (2008-05-20 11:40) [29]

Как нет гридов. Есть гриды, отображение работает, редактирование данных по организации работает, т.к. IBTable там вкачестве detail.
Редактирование, вставка и удаление в(из) таблицу Building работает.
Не работает вставка и редактирование в DetailDS3, т.е. в третий датасет в связке.


 
grav   (2008-05-20 11:46) [30]

> ЮЮ ©   (20.05.08 11:39) [28]

Пользовательские данные в данном случае не в гриде, а в DBEdit"ах, ибо зачем под одну строку отводить грид (хотя первоначально так у меня и было). Передаются запросом из InsertSQL


> В этом коде втавка пустой строки, соответсиыующкй новой
> строке в BUILDING.

Да, так и есть.

DetailDS1.Insert;
DetailDS1.FieldByName("ID_ORG").AsInteger:=OrganDS.FieldByName("ID").AsInteger;
DetailDS2.Insert;
DetailDS2.FieldByName("ID_ORG").AsInteger:=BuildDS.FieldByName("ID_ORG").AsInteg er;
DataBDS.FieldByName("ID_BUILD").AsInteger:=BuildDS.FieldByName("ID").AsInteger;
DetailDS2.FieldByName("ID_OBJ").AsInteger:=0;
SaveBtn.Enabled:=True;


 
ЮЮ ©   (2008-05-20 11:47) [31]

> т.к. IBTable там вкачестве detail.

Остется тихо удалиться :)
Хотя бы дельфийский help по мастер-детайл почитал бы.


> Тогда при добавлении в таблицу данных Из DetailDS2 возьмется
> ID_ORG=1 ID_BUILD=1, других данных в датасете не будет просто.

У тебя же  датасет &#151; IBTable. Там всё должно быть :)


> Редактирование, вставка и удаление в(из) таблицу Building
> работает.

Интересно, что можно вставить в гриде для таблицы BUILDING(ID, ID_ORG)? Или там ещё поля есть? Почему они тогда не в DATA?


 
ЮЮ ©   (2008-05-20 11:54) [32]

> DetailDS1.Insert;
> DetailDS1.FieldByName("ID_ORG").AsInteger:=OrganDS.FieldByName("ID")
> .AsInteger;
> DetailDS2.Insert;
> DetailDS2.FieldByName("ID_ORG").AsInteger:=BuildDS.FieldByName("ID_ORG")
> .AsInteg er;
> DataBDS.FieldByName("ID_BUILD").AsInteger:=BuildDS.FieldByName("ID")
> .AsInteger;
> DetailDS2.FieldByName("ID_OBJ").AsInteger:=0;
> SaveBtn.Enabled:=True;


В принципе разные знвчения &#151; для стойкости геморроя, очевидно.


> Пользовательские данные в данном случае не в гриде, а в
> DBEdit"ах, ибо зачем под одну строку отводить грид (хотя
> первоначально так у меня и было). Передаются запросом из
> InsertSQL

Блин, тут целый зоопарк каких=то датасетов пасется, хотя на все про все достаточно ровно пяти [25]

B как, интересно, DBEdit, настоленный на другой датасет, успее вставить данные промеж строк вашего кода, пишущий в другой датасет. Или огрызки кода вместо полного фрагмента, приводятся для пущей ясности?


 
grav   (2008-05-20 11:59) [33]


> Интересно, что можно вставить в гриде для таблицы BUILDING(ID,
>  ID_ORG)? Или там ещё поля есть? Почему они тогда не в DATA?
>

Есть еще поля, например коды адреса здания (из справочников).

> Хотя бы дельфийский help по мастер-детайл почитал бы.

Почитал. И в интернете много почитал. Так и не понял логику работы IBDataSet.

> > т.к. IBTable там вкачестве detail.
>
> Остется тихо удалиться :)

IBTable не мешает и работает.


 
grav   (2008-05-20 12:01) [34]


> В принципе разные знвчения — для стойкости геморроя, очевидно.

Ага :) OrganDS=MasterDS
BuildingDS=DetailDS1
Не все поправил, извиняюсь.


 
grav   (2008-05-20 12:03) [35]


> Блин, тут целый зоопарк каких=то датасетов пасется, хотя
> на все про все достаточно ровно пяти

Тк и есть 4 IBDataSet и один IBTable (остался от предыдущей редакции, работает, вот и не заменяю на IBDataSet).


 
grav   (2008-05-20 12:05) [36]

Вот запрос на вставку из InsertSQL
insert into DATA
 (ID_ORG,ID_BUILD,ID_OBJ,GEN_S, LONG_NET, PRISE_B, PRISE_M, IZNOS_B,
IZNOS_M, STEPEN_B,
STEPEN_M,
  WATER, SEWER, HEAT)
values
 (:ID_ORG,:ID_BUILD,:ID_OBJ,:GEN_S, :LONG_NET, :PRISE_B, :PRISE_M,
:IZNOS_B, :IZNOS_M, :STEPEN_B,
  :STEPEN_M, :WATER, :SEWER, :HEAT)


 
ЮЮ ©   (2008-05-20 12:17) [37]

> Вот запрос на вставку из InsertSQL

Какого датасета?


 
ЮЮ ©   (2008-05-20 12:27) [38]

DetailDS2 ?
А какой запрос на выборку?
Он редактируется в гриде или DBEdit-ах. Если второе, то когда делается Insert?


 
grav   (2008-05-20 12:33) [39]

Да, DetailDS2.

Предполагалось, что insert так grav:   (20.05.08 11:46) [30]
Т.е. должна вставиться пустая строка. Потом из dbedit"ов уже Edit.
Но не работает не только вставка, но и редактирование.
SelectSQL
select * from DATA where ID_ORG=:ID_ORG and ID_BUILD=:ID and ID_OBJ=0

ModifySQL
update DATA
set
 GEN_S = :GEN_S,
 LONG_NET = :LONG_NET,
 PRISE_B = :PRISE_B,
 PRISE_M = :PRISE_M,
 IZNOS_B = :IZNOS_B,
 IZNOS_M = :IZNOS_M,
 STEPEN_B = :STEPEN_B,
 STEPEN_M = :STEPEN_M,
 WATER = :WATER,
 SEWER = :SEWER,
 HEAT = :HEAT
where
 ID_ORG = :OLD_ID_ORG and
 ID_BUILD = :OLD_ID_BUILD and
 ID_OBJ = :OLD_ID_OBJ


 
grav   (2008-05-20 12:46) [40]

Убрал для эксперимента из DetailDS2 связывающий DataSource. Все работает.
Вообще тройная связка это нормально (MasterDS-DetailDS1-DetailDS2)?



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

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

Наверх




Память: 0.59 MB
Время: 0.022 c
2-1213251527
Yury
2008-06-12 10:18
2008.07.13
очистка каталога


2-1213459702
WebSQLNeederrr
2008-06-14 20:08
2008.07.13
WebBrowser.Navigate( page.html ) - загрузить не брать из кеша


2-1213401503
ply
2008-06-14 03:58
2008.07.13
загрузка преобразование изображений


2-1212756942
Danco
2008-06-06 16:55
2008.07.13
Как вызвать программное нажатие клавиши в играх?


15-1211994140
TUser
2008-05-28 21:02
2008.07.13
Винамп - конвертор форматов