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

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.56 MB
Время: 0.008 c
15-1211906510
Админ
2008-05-27 20:41
2008.07.13
Управление золотовалютными резервами Российской Федерации


15-1211971316
Stas
2008-05-28 14:41
2008.07.13
Рсачет расстояния


15-1211861704
vajo
2008-05-27 08:15
2008.07.13
как в меню проводника отключаеся "Свойства папки..."?


2-1213386303
lewka-serdceed
2008-06-13 23:45
2008.07.13
Chat по средствам Delphi


2-1213459535
VovKul
2008-06-14 20:05
2008.07.13
Как узнать полный путь к выделенному файлу в ShellListView?





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский