Nikolay Trifonov пишет: > Сорри, но начну новый пост, ОЕ заглючил. > > один вопрос у меня в голове не укладывается: есть таблица CHANGES, в которой > для репликации записываются в какой строчке что изменилось триггером: >
Сразу извиняюсь за размер поста, но коротко тут не скажешь... вопрос репликации достаточно сложный сам по себе, да еще индивидуальные особенности БД + конторы накладывают ограничения. Поделюсь своим решением, которое IMHO не панацея, но работает: Имеем: а) 32 филиала (автоматизированная точка розничной продажи). Кратко назовем "ПОФ" б) 1 центральный офис для автоматизированных филиалов. Кратко назовем "ПОЦО" в) система которая связана с закупкой товара у поставщиков (прием заявок от филиалов, их обработка, отправка поставщикам). "Первичные" справочники, от которых все "пляшут" - именно тут. Кратко назовем "ПОГИД" Системы ПОФ и ПОЦО написаны мною, соответственно могу делать с ними все, что хочу. Система ПОГИД работает в конторе давно, исходников нет, так что модификации допускаются на уровне БД. Нужна была система с "общими синхронизированными" справочниками и "чтобы в ПОЦО были все документы из ПОФ". В ПОФ ДОПУСКАЕТСЯ заведение новых записей в справочники! Долго думал, в итоге получилась такая конфигурация ПО (только то, что касается репликации): 1) ПОФ и ПОЦО используют один и тот же исполняемый файл (что значительно облегчило мою работу) и отличаются нюансами "реализации" БД (несколько иной набор "служебных" таблиц, триггеров и ХП). а) Реализован встроенный механизм импорта справочников из ПОГИД, в котором готовятся 9 файлов со справочниками: товары, контрагенты и т.д. В справочниках ПОФ и ПОЦО используется простой PK с заполнением по генератору, во всех справочниках есть поле "ссылка_на_погид" в котором должно храниться значение PK из ПОГИД. Когда импортируется запись в справочник ПОФ или ПОЦО - проверяется наличие такого значения в "ссылка_на_погид", если оно есть - то update, если нет - то insert. Когда запись заноситься юзером, то поле "ссылка_на_погид" is null. Когда формируется пакет данных из ПОФ для ПОЦО то из справочников ПОФ выбираются записи у которых "ссылка_на_погид" is null, которые потом импортируются (через "таблицу перекодировок": "код филиала"-"PK_в_филиале" - "PK_в_ЦО"...) в БД ПОЦО. Это упрощенно, так как на самом деле проверяется наличие "такой" записи, если она есть - то импорта не происходит - проставляется код существующей записи. В ПОЦО работает еще одна программа, которая смотрит БД ПОЦО на наличие is null и позволяет указать код соответствующего PK из ПОГИД. В результате в филиал отправляется файл, который содержит информацию "код филиала"-"PK_в_филиале" - "PK_в_ПОГИД" - "таблица", когда он импортируется, то в соответствующей записи поле "ссылка_на_погид" становится равна "PK_в_ПОГИД" и она перестанет передаваться в ПОЦО. При следующем импорте справочников в ПОФ - данная строка будет обновлена полностью. Плюс в БД ПОФ реализован механизм "перехода на PK с наибольшим значением для общего "ссылка_на_погид"". Допустим есть две строки в справочнике: pk - "ссылка_на_погид" 1 100 2 100 это не очень красиво, поэтому при проставлении значения в поле "ссылка_на_погид" проверяется наличие записей с таким же значением и с помощью триггера происходит перенос данных на новый код, например вот так: AS declare variable tmp_analog_id integer; begin if (new.parent_id is not null) then begin for select an.analog_id from analog an where an.parent_id = NEW.PARENT_ID and an.analog_id <> NEW.analog_id into :tmp_analog_id do begin update defectureitem di set di.analog_id = NEW.analog_id WHERE di.analog_id = :tmp_analog_id; update sprice sp set sp.analog_id = NEW.analog_id WHERE sp.analog_id = :tmp_analog_id; update goods gd set gd.analog_id = NEW.analog_id WHERE gd.analog_id = :tmp_analog_id; delete from analog an where an.analog_id = :tmp_analog_id; end end end /*конец триггера*/ в итоге имеем "красивые и синхронизированные" справочники, причем никто не ограничивает из заполнение в ПОФ. Для этого нужно: процедура импорта справочников из ПОГИД, выгрузка "заведенных" в ПОФ записей в ПОЦО, импорт в ПОФ ссылок из ПОЦО. б) теперь касаемо документов и связанных с ними таблиц. Все документы, которые влияют на товарный запас имеют набор триггеров, которые фиксируют в "таблицах состояния" необходимость передачи этого документа в ПОЦО. Например вот так: AS begin /*добавление документа в список синхронизируемых*/ UPDATE sync$move sm SET sm.time_send = null, sm.time_recv = null WHERE sm.pr_key = NEW.move_id; IF (row_count = 0) THEN BEGIN INSERT INTO sync$move (pr_key) VALUES(NEW.move_id); END end AS begin /*удаление документа из списка синхронизируемых*/ DELETE FROM sync$move sm WHERE sm.pr_key = OLD.move_id; /*добавление документа в список удаляемых*/ DELETE FROM sync$deleted sd WHERE sd.table_name = 'MOVE' AND sd.pr_key = OLD.MOVE_ID; INSERT INTO sync$deleted (table_name,pr_key) VALUES('MOVE',OLD.move_id); end при формирование пакета данных из ПОФ в ПОЦО выбираются данные у которых WHERE NOT EXISTS (SELECT sm.pr_key FROM sync$move sm WHERE sm.pr_key = mo.move_id AND sm.time_send IS NOT NULL AND sm.time_recv IS NOT NULL) когда этот пакет (содержит 9 файлов) приходит в ПОЦО, то робот пытается его загрузить. По окончании импорта формируется пакет "квитанций" (1 файл), при обработке которого в ПОФ UPDATE sync$move sm SET sm.time_recv = :time_recv WHERE sm.pr_key = :pr_key; И этот документ больше не выгружается из ПОФ в ПОЦО (до тех пор пока его кто нибудь не "тронет"). Итого: для синхронизации документов (из ПОФ в ПОЦО) нужно подготовить пакет в ПОФе (9 файлов), обработать его в ПОЦО и вернуть квитанцию (1 файл). В БД ПОЦО не используется "составных" PK (филиал+PK_в_филиале), а используется "таблицы перекодировок". Это позволило не менять исполняемый файл, оставить всю логику неизменной. Для этого поступил так: в каждом ПОФ есть несколько отделов (складов), при переносе документов в БД ПОЦО не происходит "кучкование" документов на 1 "синтетический" отдел, соответствующий этому ПОФу, а каждый отдел ПОФа является полноценным отделом в ПОЦО. 2) Для передачи данных используется dbf пожатый zip, канал передачи ftp (off-line). 3) Для обработки данных от ПОФ написан сервис, который по таймеру ищет на фтп-сервере данные от ПОФ и импортирует их в БД ПОЦО. По результатам импорта, в ПОФ отправляется файл, в котором указаны PK УСПЕШНО обработанных записей. Пока такого подтверждения не получено - филиал будет слать эту запись в ПОЦО. Это если коротко. Если нужна "конкретика" - спрашивай... Рубан Станислав