Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как пробежаться по строкам DBMemo? [D7, XP]


Страницы:   1 2

azamatufa ©   (2010-07-05 09:52:00) 

Есть FireBird, Delphi7, TIBDataSet в нем DBMemo поле.
Хочу в это Мемо содержать строки такого формата:
--------------------------------
2004-2005 | менеджер ООО Феникс
2005-2006 | складовщик ЗАО Пупкин
2006-2007 | зам.директора ОАО МММ
--------------------------------
т.е. трудовая деятельность человека, где "|" - разделитель.

Так, я должен писать и читать от туда.

Спасибо!


azamatufa   (2010-07-09 07:22:00) [1]

Еще раз, спасибо за Ваш опыт!


Юрий Зотов   (2010-07-07 07:35:00) [2]


> azamatufa ©   (06.07.10 09:26) [27]

Вопросы 1 и 2: непринципиально, как удобнее - так и делайте. Можно, например делать и так - вместо поля Prev_ID ввести поле "счетчик", а первичным ключом задать сочетание полей ID и Счетчик. Тогда получится что-то типа этого:

ID  Счетчик  Имя      Отчество
1       0        Вера     Петровна
1       1        Мария   Петровна
1       2        Иван     Иваныч

Тогда ID идентифицирует самого человека, а счетчик - номера относящихся к нему записей. Действующая запись имеет максимальное значение счетчика.

Вопрос 3: Вы сами на него уже ответили - ключ должен содержать ID филиала, тогда повторов не будет. Главное тут не это, а вот что.

Допустим, в филиале сделали запись в некую таблицу. Потом провели слив в центральную базу и там эта запись тоже появилась. Сразу возникают вопросы, требующие решения:

а). кто имеет право видеть эту запись (внесший филиал, центр, все филиалы и т.п.)?

б). в последнем случае - как обновить БД других филиалов (там же тоже эта запись должна появиться)?

в). кто имеет право изменять/удалять эту запись (внесший филиал, центр, все филиалы и т.п.)?

г). при модификации/удалении записи - как обновить БД других филиалов (там же тоже эта запись должна измениться/удалиться)?

===========================

Лет 5-6 назад довелось мне делать именно такую распределенную БД, и филиалов тоже было примерно как у Вас. Главной проблемой оказалась именно синхронизация БД (репликация) с учетом прав доступа - особенно, из-за того, что записи могли быть дочерними и родительскими. Например.

1. Филиал Ф1 внес родительскую запись РЗ и дочернюю к ней ДЗ. Дочерняя запись, естественно, ссылается на родительскую.

2. Филиал Ф2 должен видеть запись ДЗ, но ни при каких условиях не должен видеть записи РЗ. То есть, записи РЗ в БД филиала Ф2 просто не должно быть - и тогда в записи ДЗ в БД филиала Ф2 появляется битая ссылка. Нарушение ссылочной целостности, ни больше, ни меньше - и, тем не менее, все обязано работать.

Для решения в каждой БД был заведен журнал изменений (состоял из несколькких таблиц) и написан специальный модуль репликаций. В журнале каждого филиала фиксируются все изменения, сделанные филиалом в его БД, затем эти изменения выгружаются на диск в виде XML. Этот XML проигрывается в центральную БД и формируется другой XML. Получив его, все филиалы соответственно обновляют свои БД, а филиал-источник очищает ставшие ненужными записи в своем журнале изменений.

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


azamatufa   (2010-07-06 09:26:00) [3]


> Юрий Зотов

Огромное спасибо за такой ответ!

Пару вопросов:

1. Вместо Prev_ID (который надо постоянно изменять) можно ведь постоянно тоскать с собой первоначальный ID (в поле Prev_ID) ? А хронологию по дате сечь...

ID Prev_ID Otchetstvo
1   1    Петровна
2   1    Николавна
3   1    Иванович (стал мужиком наконец)   (End_Date - null)

2. В таблице должностных перемещений на какой ID_работника ссылаться? на первоначальный? или на последний актуальный..? (тоже вроде бы и так и так можно.. )

3. И еще больной вопрос: как правильно сливать данные от всех филиалов.. ведь ID'ы плывут... Мне кажется, надо в каждой таблице иметь поле Filial_ID...
и составной индекс Filial_ID + ID - например в таблица людей.

Спасибо!

p.s. Еще раз спасибо за отличные идеи и мысли! Я обязательно это возьму на вооружение!


Юрий Зотов   (2010-07-05 16:53:00) [4]

> azamatufa ©   (05.07.10 15:15) [23]

Во-первых, сразу же напрашивается отдельная таблица "Справочник филиалов" с полями ID (перв. ключ), Name (not null, unique) и любыми еще другими, какие нужны.

Вторая таблица - справочник должностей. Поля примерно те же - ID (перв. ключ), Name (not null, unique) и любые еще другие, какие нужны.

Третья таблица - справочник статусов (действующий, резервист, исключен и т.д.). Поля примерно те же.

Четвертая таблица - личные данные работников. Поля примерно такие:

ID (перв. ключ)
Prev_ID (ссылка на ID предыдущей записи в той же таблице; null означает, что эта запись первичная и предыдущей записи у нее нет)
Start_Date (дата начала действия записи, not null)
End_Date (дата окончания действия записи, null означает действующую)
Фамилия
Имя
Отчество
Пол
Дата рождения
и прочие редко изменяемые или совсем неизменяемые данные работников

Заметьте, что такая таблица может хранить не только текущие данные работника, но и всю историю их изменений. Например, она позволяет отследить, что нынешний Иван Иваныч пять лет назад сменил ФИО и пол, а до этого он был Марьей Петровной, а еще тремя годами раньше он был Верой Петровной.

Если нет отдельного справочника адресов (КЛАДР, например), то адрес нашего Иваныча тоже можно подстыковать в эту таблицу. После этого пусть он переезжает хоть каждый день - вся история его переездов тоже будет храниться. Как и смена номеров телефонов, если в эту же таблицу прицепить и телефон.

В общем, что хранить с историей, а что без нее - это решать Вам совместно с заказчиком.

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

ID (перв. ключ)
Prev_ID (ссылка на ID предыдущей записи в той же таблице; null означает, что эта запись первичная и предыдущей записи у нее нет)
ID_филиала (ссылка на справочник филиалов)
ID_должности (ссылка на справочник должностей)
ID_статуса (ссылка на справочник статусов)
ID_работника (ссылка на первичную запись в таблице работников)
Start_Date (дата начала действия записи)
Номер_приказа_1 (на основании чего запись начала действовать)
End_Date (дата прекращения действия записи)
Номер_приказа_2 (на основании чего запись перестала действовать)
и т.п.

Заметьте, что эта таблица тоже хранит всю историю должностных перемещений - и наш Иваныч теперь как на ладони. Например, в любой момент мы можем определить, что в период с... по... он работал кладовщиком в филиале № 7 и получал 100 тыс. баксов в месяц. Причем в то время он был еще Петровной, а не Иванычем.

=============

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


Anatoly Podgoretsky   (2010-07-05 15:33:00) [5]

> azamatufa  (05.07.2010 15:15:23)  [23]

Это не сложно, достаточно добавить два поля - начало и конец действия
записи.


12   (2010-07-05 15:21:00) [6]

> Может Вы сделаете срез "моих" желаний и дадите ЦУ в каком
> направлении думать дальше.....

Я не ЮЗ, но если бы я был ЮЗ, я бы направил читать теорию разработки БД


azamatufa   (2010-07-05 15:15:00) [7]


> Юрий Зотов

Хорошо, уважаемый Юрий! Раз Вы хотите меня направить на путь истинный, позволю себе проконсультироваться у Вас и, конечно же, у не менее уважаемого All'a ;)

"Кадровая (узкопрофильная) программа".
Есть 40 филиалов. В каждом работает по 100 человек.
Раз в полгода (или чаще) они должны "выгружать" мне свои данные.
Каждый человек может "двигаться":
- быть действующим работником
- просто состоять в кадровом резерве
- быть действующим + состоять в кадровом резерве
- действующий/резервист может быть назначенным на должность (+ снова зачислиться в резерв)
- быть исключен из кадрового резерва

Чтоб сделать все по уму, как Вы сказали, надо предусмотреть "версионность" записей (историю)..  а это (пока кажется что) сложно.... (((

Я (пока) выбрал вариант, когда идет конкретный дубляж данных:
отдельная таблица действующих
отдельная таблица резервистов
и т.п.

Может Вы сделаете срез "моих" желаний и дадите ЦУ в каком направлении думать дальше.....

Спасибо!


Юрий Зотов   (2010-07-05 12:52:00) [8]

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


Anatoly Podgoretsky   (2010-07-05 12:21:00) [9]

> azamatufa  (05.07.2010 11:53:18)  [18]

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


Anatoly Podgoretsky   (2010-07-05 12:20:00) [10]

> azamatufa  (05.07.2010 11:15:15)  [15]

Красиво печатать из базы данных, а не из мемо, и проще.


12   (2010-07-05 12:18:00) [11]

SS:tstrings;

begin
 memo1.Lines.Text := SS.Text


azamatufa   (2010-07-05 11:53:00) [12]


> Юрий Зотов

Про нормальные формы я более менее слышал. В моем же случае тока одна запись про Иван Ивановича!

Гуру, подскажите как вогнать из TStrings в memo!


Юрий Зотов   (2010-07-05 11:19:00) [13]

А для красивой печати существуют отчеты.


Юрий Зотов   (2010-07-05 11:19:00) [14]

> azamatufa ©   (05.07.10 11:15) [15]

И сколько же строк в этой таблице будет соответствовать ОДНОМУ И ТОМУ ЖЕ ИванИванычу? Он ведь адрес, телефон и место работы может хоть каждый день менять.


azamatufa   (2010-07-05 11:15:00) [15]


> Юрий Зотов

не уговаривайте)))
у меня по задумке одна табличка: Иванов,Иван,Иванович,муж,1962,место_работы,адрес,тел,трудовая_деятельность
"трудовая деятельность" - мог и просто TDBMemo, но хочу в последующем красиво печатать... поэтому и горожу огород....


azamatufa   (2010-07-05 11:10:00) [16]

Прошу прощения...

вот я считал так:
TrudMemo := TStream.Create;
 TrudMemo := DM.Uchet_Card.CreateBlobStream(DM.Uchet_Card.FieldByName('TRUD_DEYAT'),bmRead);

 TrudList := TStringList.Create;
 TrudList.LoadFromStream(TrudMemo);


а как бы теперь записать из TStrings в блоб (т.е. обратно)?

Спасибо!


Юрий Зотов   (2010-07-05 11:10:00) [17]

> azamatufa ©   (05.07.10 10:43) [8]

> не охота еще одну таблицу делать для этого... (это про "еще проще")

А кто заставляет? Надо просто написать select, он соберет данные хоть из 100 разных таблиц - и не нужны никакие новые таблицы. А самый обычный DBGrig вполне успешно все это отобразит, без лишних телодвижений.


Anatoly Podgoretsky   (2010-07-05 11:00:00) [18]

> Anatoly Podgoretsky  (05.07.2010 10:47:09)  [9]

Не создавать DBMemo, а гнать потоком куда надо или превратить memo в string


azamatufa   (2010-07-05 10:54:00) [19]

TStream?


azamatufa   (2010-07-05 10:50:00) [20]


> Anatoly Podgoretsky

а как? )))


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо