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

Вниз

Master-Detail многие ко многим?   Найти похожие ветки 

 
Felan ©   (2004-04-21 11:58) [0]

Есть база на InterBase 6.0 и программа-клиент пишущаяся на D6 c FIB+ 5.2.

На форме есть два pFIBDataSet"a у каждого из которых есть свой DataSource. Первый pFIBDataSet выбирает из таблицы коды значений, второй по этим кодам выбирает занчения из других таблиц и показывает их в DBGrid.

SQL запросы выполняются путем установки свойства Active у pFIBDataSet (которые и содержат эти запросы, естественно)

Запрос второго pFIBDataSet"a содержит параметры, которые берутся из первого DataSource. Т.е. у втрого pFIBDataSet"a в свойстве DataSource прописан первый DataSource.

Все это работает, но DBGrid (второй DataSource) содержит только одну строку значений, котороая соответствует первой (в общем случае активной) строке параметров из первого DataSource (типичное отношение Master-Detail).

Вопрос, как сделать так, что бы DBGrid отображались значения, соответствующии всем строкам кодов из первого DataSet.

Нутром чую, что таким способом это не получтися, но как? Понятно, что для этого надо делать объединение таблиц в запросе во втором pFIBDataSet, но, дело в том, что это противоречит принципиальному моменту: коды занчений должны поставляться независимо от значений (разными pFIBDataSet"ами), т.е. надо в одном запросе получать коды значений (строки из одной таблицы), а во втором отображать значения, в соответствии с этими кодами (т.е. это теже строки, только вместо цифр нормальные названия).

Какие есть пути решения проблемы? Желательно на примерах... ссылки на толковые статьи приветствуются.

Зарание спасибо!


 
Соловьев ©   (2004-04-21 12:04) [1]

Ну и какая же здесь мастер-детайл?
повесить на событие AfterScroll первого сорса ExLocate второго, где позиционировать на первую запись соответсвующую связи.


 
Курдль ©   (2004-04-21 12:05) [2]

Может еще проще использовать Lookup-поля?
Но, несомненно, лучше всего получить все одним запросом с сервера и не париться!


 
Johnmen ©   (2004-04-21 12:15) [3]

>Felan ©  

Вообще говоря всё должно работать. Естественно при корректном указании всех необходимых свойств.
Поэтому, возможно, есть неточности в запросах 1 и 2.


 
Anatoly Podgoretsky ©   (2004-04-21 12:20) [4]

Ошибка в запросах детайл таблицы


 
Соловьев ©   (2004-04-21 12:31) [5]


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

Это не мастер-детайл


 
Felan ©   (2004-04-22 14:47) [6]

Так. Поясняю по порядку.

То Олл: Я имел ввиду, что не мне надо организовать Master-Detail, а что фактически работает Master-Detail. Потому то я и написал сюда, что не погу сообразить как это обойти или как сделать подругому.

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

То Курдль: Лукап поля показывают одно значение, а надо таблицу... Прчем эта таблица есть таже таблица, что в первом, но только вмето кодов выводятся заначения из др. таблиц. Я дальше приведу запросы.

То Anatoly Podgoretsky & Johnmen: Да не, запросы работают, это просто так работают компоненты. Если в одном указать как источник параметров другой, то параметры беруться не из всего множества строк, а только из текущей (мне надо что б из всех строк брались), это и есть мастер-детайл :)

Запросы выглядят так:

Первый SELECT * FROM tabel_select_dep1;
Вы водит примерно такую таблицу:


 
stud ©   (2004-04-22 14:56) [7]

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


 
Felan ©   (2004-04-22 14:59) [8]

Так. Поясняю по порядку.

То Олл: Я имел ввиду, что не мне надо организовать Master-Detail, а что фактически работает Master-Detail. Потому то я и написал сюда, что не погу сообразить как это обойти или как сделать подругому.

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

То Курдль: Лукап поля показывают одно значение, а надо таблицу... Прчем эта таблица есть таже таблица, что в первом, но только вмето кодов выводятся заначения из др. таблиц. Я дальше приведу запросы.

То Anatoly Podgoretsky & Johnmen: Да не, запросы работают, это просто так работают компоненты. Если в одном указать как источник параметров другой, то параметры беруться не из всего множества строк, а только из текущей (мне надо что б из всех строк брались), это и есть мастер-детайл :)

Запросы выглядят так:

Первый
SELECT * FROM tabel_select_dep1;
Вы водит примерно такую таблицу:

S_CODE S_DEP S_EMP S_POST S_RATE S_CLASS S_ACCEPTDATE
1 7 2 6 1 13 03.10.2003
2 7 1 10 2 6 23.02.2004
3 1 2 2 3 17 18.01.2004

S_FIREDATE S_CONTRACT
15.03.2004 FpWRXwvZ
07.04.2004 pdQiNHv
null            ""
И Т.Д.

Второй (упращен до запроса к одной таблице)
SELECT * FROM TABEL_EMPLOYEE
WHERE (E_CODE in (:s_emp));

Выводит только одну строку из соотв. таблицы:
E_CODE E_NUM E_FAM E_NAM E_PAT
2 0 Пупкин Василий Алибабаевич

(очевидно, связь по полю s_emp - e_code)

А должен выводиться список в соответствии с первым запросом.

Еще раз хочу сказать, что проблем SQL нет! И правильный запрос, сам по себе я составлю без проблем. Я не соображу, как в принципе разнести получение параметров и вывод данных по ним.

Возможно предложение Соловьева сработает, сейчас попробую покапаться.


 
Felan ©   (2004-04-22 15:00) [9]

Блин, все форматирование таблиц похерилось :(
Вобщем там на одно поле одно однозначное число либо дата... В послследнем только строка.


 
stud ©   (2004-04-22 15:00) [10]

т.е. ты имееш один набор
код1
...
кодn
и хочеш, чтобы во втором наборе выводилось
код1 название
.....
кодn название
зачем тогда превый набор нужен? если вся информация во втором наборе содержится?


 
stud ©   (2004-04-22 15:05) [11]

тогда
SELECT * FROM TABEL_EMPLOYEE
WHERE (E_CODE in (select pole from....));
а иначе ты и получиш одну строку


 
Johnmen ©   (2004-04-22 15:09) [12]

Тогда второй запрос
SELECT * FROM TABEL_EMPLOYEE
JOIN tabel_select_dep1 ON tabel_select_dep1.E_CODE =
 TABEL_EMPLOYEE.s_emp


 
Felan ©   (2004-04-22 15:24) [13]

То stud:
Нет, это я для примера привел полный вывод, что б понятно было.
Во первых, во втором наборе должно выводиться только
название
.....
название

Во вторых, зачем не это надо? Затем, что бы вынести управление выводом на сервер, а не на клиенте запросы формировать... (кстати, мне тут одна мысль счас пришла, может действительно одним обойтись...), т.к. нехочется по каждому пустику переписывать приложение.

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

Т.е. второй запрос одинаковый для всех по определению, а первы может меняться в зависимости от пользователя...


 
stud ©   (2004-04-22 15:39) [14]

так а два запроса всетаки зачем??


 
Felan ©   (2004-04-22 16:50) [15]

То stud:
Не знаю... книнануло меня почему-то на двух запросах! Вот теперь думаю... вариант Johnmen"а вполне подходит... хотя идеология конечно не та...


 
stud ©   (2004-04-22 16:58) [16]

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


 
Felan ©   (2004-04-22 17:05) [17]

...и, кажется он с именами таблиц напутал... блин, уже башка вообще не соображает. Потом осмыслю его запрос.


 
kaif ©   (2004-04-23 04:08) [18]

Master-Detail связь датасетов бывает нужна, когда ты хочешь при скроллинге в первой сетке чтобы что-либо менялось во второй. Если же у тебя во второй сетке должно что-то отображаться, опираясь на все значения в первой сетке, как в данном случае, то делать мастер-детейл датасетов неразумно ни в каком смысле.
Я так понял, что в левой сетке - список каких-то контрактов, а во второй - список работников, которые их выполняют или что-то в этом духе. Здесь нужны два изолированных запроса к серверу. Второй запрос должен сам все сделать (вроде того, что предложили Stud и Johnmen). Возможно, что во втором запросе distinct может понадобиться, если один работник сразу по двум контрактам работает, а нужно его один раз высвечивать.
 В любом случае мастер-детейл здесь не нужен и вреден.


 
Felan ©   (2004-04-23 15:09) [19]

То kaif: Блин, да ЗНАЮ Я, ЧТО ЭТО НЕ МАСТЕЙ-ДЕТАЙЛ!!! Прежде чем отвечать, хоть бы внимательно прочитал про что речь. А вот перефразировал ты мой вопрос верно :) Дело в том, что если второй делает все сам, то нафиг тогда первый?

То Johnmen: В принципе твой вариант работает, только вот tabel_select_dep1 это ХП, и она как раз зависит от пользователя (у каждого совоя), поэтму неподходит...

Я хотел построить такуюю структуру:

Есть сводная таблица staff, как почти правильно подметил kaif, в ней коды отделов, сотрудников и прочее, короче кто-где-когда. Есть таблици, в котрые есть "расшифровки" этих кодов (например employee - сотрудники, department - отделы и т.д.)
У каждого отдела есть свое представление staff_n, где n-номер отдела. Так же есть хранимые процедуры для каждого представления, просто для того, что бы все это редактировалось на сервере, и, если что, звращать выборку как угодно.

Далее, на клиенте, как я уже говорил, должно быть два запроса, один исполняя процедуру (также есть таблица, какому юзеру, какая процедура нужна) получает сводную таблицу кодов из нужного предстваления staff_n. А второй запрос по этим кодав отображает информацию. Т.о. получаем независимость оработки результатов, от их выборки. Т.е. если какому-т опользователю надо что-то изменить в доступе и прочее, меняется только его ХП, а клиент как работал, так и работает.

Вот, собственно то, что я хотел...

Теперь я думаю, почитав все что вы писали, что может и не стоит так извращаться... можно ведь отдельно запрос хранить для каждого пользователя... тем более, что у FIB есть репозиторий запросов... или все реилизовать в одной ХП...

Эх, блин, нелегко определиться в первый раз :)


 
Felan ©   (2004-04-23 15:10) [20]

То kaif: Блин, да ЗНАЮ Я, ЧТО ЭТО НЕ МАСТЕЙ-ДЕТАЙЛ!!! Прежде чем отвечать, хоть бы внимательно прочитал про что речь. А вот перефразировал ты мой вопрос верно :) Дело в том, что если второй делает все сам, то нафиг тогда первый?

То Johnmen: В принципе твой вариант работает, только вот tabel_select_dep1 это ХП, и она как раз зависит от пользователя (у каждого совоя), поэтму неподходит...

Я хотел построить такуюю структуру:

Есть сводная таблица staff, как почти правильно подметил kaif, в ней коды отделов, сотрудников и прочее, короче кто-где-когда. Есть таблици, в котрые есть "расшифровки" этих кодов (например employee - сотрудники, department - отделы и т.д.)
У каждого отдела есть свое представление staff_n, где n-номер отдела. Так же есть хранимые процедуры для каждого представления, просто для того, что бы все это редактировалось на сервере, и, если что, звращать выборку как угодно.

Далее, на клиенте, как я уже говорил, должно быть два запроса, один исполняя процедуру (также есть таблица, какому юзеру, какая процедура нужна) получает сводную таблицу кодов из нужного предстваления staff_n. А второй запрос по этим кодав отображает информацию. Т.о. получаем независимость оработки результатов, от их выборки. Т.е. если какому-т опользователю надо что-то изменить в доступе и прочее, меняется только его ХП, а клиент как работал, так и работает.

Вот, собственно то, что я хотел...

Теперь я думаю, почитав все что вы писали, что может и не стоит так извращаться... можно ведь отдельно запрос хранить для каждого пользователя... тем более, что у FIB есть репозиторий запросов... или все реилизовать в одной ХП...

Эх, блин, нелегко определиться в первый раз :)


 
Johnmen ©   (2004-04-23 15:17) [21]

>только вот tabel_select_dep1 это ХП, и она как раз зависит от
>пользователя (у каждого совоя),
и
>Т.е. если какому-т опользователю надо что-то изменить в доступе
>и прочее, меняется только его ХП,

Крайне нежелательный подход. Т.к. связан с постоянным изменением метаданных.
У каждого п-ля, если надо, д.б. своя запись или набор записей в общей таблице...


 
stud ©   (2004-04-23 15:43) [22]

а каким образом пользователь идентифицирутся? где его идентификатор фигурирует?
зачем писать каждому пользователю отдельнуб процедуру???

> Johnmen ©   (23.04.04 15:17) [21]

достаточно в таком случае одной, где в качестве параметра передавать ид пользователя


 
Felan ©   (2004-04-23 16:28) [23]


> Крайне нежелательный подход. Т.к. связан с постоянным изменением метаданных.

А что такого плохого в изменении ХП?


> У каждого п-ля, если надо, д.б. своя запись или набор записей
> в общей таблице...

Не совсем понял, что ты тут имел ввиду? Хочешь сказать ,что надо добавить каждой записе еще и ид пользователя???


> а каким образом пользователь идентифицирутся? где его идентификатор фигурирует?

Ну как каким? Вроде это на уровне СУБД происходит :) Есть же системные таблицы, где права прописаны, и служебная база данных, в которой пользователи сервера лежат... вот ее чуток модифицировать и айди там есть, только в 6.0 не используется и его руками вести надо... (возможно лучше будет в базе аналог таблици сделать, а при обращении в триггере обновлять?..)

Кстати, то Олл: А стоит ли вообще связываться с системными таблицами? Я имею ввиду их модификацию, понятно, что просто прочитать оттуда что-нибудь всегда полезно :)


> зачем писать каждому пользователю отдельнуб процедуру???

Ну а какая разница? Ну будет айди параметром передаваться, фактически то же самое, каждому свой код.


 
Felan ©   (2004-04-23 16:34) [24]

И еще, есть ли какой нибудь способ обращаться к таблицам служебной базе данных через рабочую, если в свойствах соединения указа служебная (когда в IBExpert регистришь базу, там есть пункт такой), или ей обязательно отдельное соединение надо?


 
stud ©   (2004-04-23 16:43) [25]

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

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


 
Felan ©   (2004-04-26 10:40) [26]


> модифицировать системные таблицы можно, но вот нужно ли?)))

А как же? В 6.х поля UID и GID в служебной базе не используются :(
Надо добавить генератор и триггер... да плют седлать его notnull и уникальное ограничение добавить... Так что надо :(
Иначе как ID придется имя использовать.


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

Ну, до того как разнесли мою идею с "каждому свою хп" он в запросах вообще не фигурировал :)
Теперь даже не знаю... видимо в зависимости от него будет происходить обращение к соответствующим просмотрам... хотя... может быть стоит и от просмотров отказаться?
Если честно, я не совсем понял, что ты имел ввиду. Что значит, как фигурирует???


 
stud ©   (2004-04-26 10:56) [27]


> Надо добавить генератор и триггер

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

> Если честно, я не совсем понял, что ты имел ввиду. Что значит,
> как фигурирует???

например выдать все данные. относящиеся к конкретному пользователю:
select * from table where table.userid=:id или что-то в этом роде


 
Felan ©   (2004-04-26 11:15) [28]


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

Ну не знаю, я сюда написал потому, что занаю, "как должен быть забит гвоздь, но не знаю какие для этого есть ГОТОВЫЕ инструменты и чем (чем лучше) это сделать". Зачем делать свою таблицу, когда она уже есть? Зачем тогда использовать вообще IB, можно свою СУБД написть? Не знаю, если все делать самому, то я бы и сделал... через n лет. Дело в том, что не хочу опять изобретать колесо! Меня, например, сильно разочаровало, что UID надо самому обслуживать (уж казалось бы, насколько элементарная и нужная рюшечка)... ибо это число, а его можно привезать к репозиторию, с которым могут работать FIB+. Если вести такую таблицу самому, то зачем тогда системная??? Их же синхронизировать надо будет... Разници нет никакой. К тому же, служебная база не имеет никакого отношения к базе. Она только сервак обслуживает, ты всегда можешь ее заменить на родную (немодифицированную).


> > Если честно, я не совсем понял, что ты имел ввиду. Что
> > значит, как фигурирует???
> например выдать все данные. относящиеся к конкретному пользователю:
> select * from table where table.userid=:id или что-то в
> этом роде

Эээ, ну это то понятно, что он в условиях занят... чет помоему мы не поняли тут друг друга...


 
stud ©   (2004-04-26 11:33) [29]


> К тому же, служебная база не имеет никакого отношения к
> базе. Она только сервак обслуживает, ты всегда можешь ее
> заменить на родную (немодифицированную).

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


 
Felan ©   (2004-04-26 11:44) [30]


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

А! Я понял :) Давай не будем мешать в одно системные таблици, которые являются частью БД и для каждой свои, и служебную базу (которая isc4.gdb) :)
В системных таблицах не храняться пользователи, в них раниться только права, роли и прочее, что имеет отношение только к конкретной базе. А isc4.gdb хранит инфу по пользователям всего сервера... Строго говоря это и есть пользователи, а остально это разрешения :)


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

Ну не знаю... зачем в таблице пользователей хранить "что угодно"? Она нато и таблица пользователей, что бы в ней пользователей хранить ;) Там вроде и так все понятно...


 
stud ©   (2004-04-26 11:56) [31]

хозяин - барин)))


 
Felan ©   (2004-04-26 13:27) [32]

stud, у тя аська есть? Стукнись 145621848, вдруг когда еще сгодимся друг другу :)



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

Форум: "Базы";
Текущий архив: 2004.05.23;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.57 MB
Время: 0.039 c
3-1083074531
AlexBalex
2004-04-27 18:02
2004.05.23
Обновление указанной записи с помощью resync


9-1074423637
ZAROLF
2004-01-18 14:00
2004.05.23
2D аркада "SPACEMAN"


14-1083253487
афвуд
2004-04-29 19:44
2004.05.23
Не подскажет кто исходники(C, Pasca) какой-нибудь скриптогонялки.


4-1081417029
KORN
2004-04-08 13:37
2004.05.23
DialogBox (скрытие окна)???????????????????????????


4-1080803647
melnikov ivan
2004-04-01 11:14
2004.05.23
Как пользоваться функцией VirtualQueryEx()?





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