Форум: "Базы";
Текущий архив: 2005.10.23;
Скачать: [xml.tar.bz2];
ВнизНужна критика :) - репликации в FB Найти похожие ветки
← →
Андрей Жук © (2005-09-12 18:04) [0]Текущее состояние дел.
В БД в таблицах, в которых нужно делать репликацию, добавил поле LAST_UPDATED. Заполняется триггером.
Создал дополнительную таблицу APP_TABLES со следующей структуройCREATE TABLE APP_TABLES (
TABLE_ID IDENTIFIER NOT NULL /* IDENTIFIER = INTEGER NOT NULL */,
TABLE_NAME NAME NOT NULL /* NAME = VARCHAR(82) DEFAULT "unknown" NOT NULL */,
TABLE_DESC DESCRIPTION /* DESCRIPTION = VARCHAR(255) */,
IS_LOGGED BOOLEAN /* BOOLEAN = VARCHAR(1) DEFAULT "U" NOT NULL CHECK (value in ("Y","N","U")) */,
PRIMARY_KEY NAME COLLATE WIN1251_UA /* NAME = VARCHAR(82) DEFAULT "unknown" NOT NULL */,
EXPORT_ORDER NONIDENTIFIER /* NONIDENTIFIER = INTEGER */
);
Создана таблица точек сохраненияCREATE TABLE APP_SAVEPOINTS (
SAVEPOINT_ID IDENTIFIER NOT NULL /* IDENTIFIER = INTEGER NOT NULL */,
SAVEPOINT_NAME NAME NOT NULL /* NAME = VARCHAR(82) DEFAULT "unknown" NOT NULL */,
SAVEPOINT_DESC DESCRIPTION /* DESCRIPTION = VARCHAR(255) */,
SAVEPOINT_DATETIME TIMESTAMP NOT NULL,
SAVEPOINT_CREATOR NAME COLLATE WIN1251_UA /* NAME = VARCHAR(82) DEFAULT "unknown" NOT NULL */,
IS_ACTIVE BOOLEAN DEFAULT "N" NOT NULL COLLATE WIN1251_UA /* BOOLEAN = VARCHAR(1) DEFAULT "U" NOT NULL CHECK (value in ("Y","N","U")) */
);
Создана процедура, которая делает XML изменившихся параметровCREATE PROCEDURE GET_UPDATES
RETURNS (
RES VARCHAR(32000))
AS
DECLARE VARIABLE TMP VARCHAR(4096);
DECLARE VARIABLE TABLE_NAME CHAR(31);
DECLARE VARIABLE FIELD_NAME CHAR(31);
DECLARE VARIABLE XML VARCHAR(4096);
DECLARE VARIABLE TABLE_ID INTEGER;
DECLARE VARIABLE RECORD_ID INTEGER;
DECLARE VARIABLE FIELD_CHAR INTEGER;
DECLARE VARIABLE FIELD_NULL INTEGER;
DECLARE VARIABLE PK CHAR(31);
BEGIN
TABLE_ID = 1;
FOR
SELECT RDB$RELATIONS.RDB$RELATION_NAME, APP_TABLES.primary_key
FROM RDB$RELATIONS, APP_TABLES
WHERE RDB$RELATIONS.RDB$SYSTEM_FLAG = 0 AND
RDB$RELATIONS.RDB$RELATION_NAME = APP_TABLES.TABLE_NAME AND
APP_TABLES.IS_LOGGED = "Y"
ORDER BY APP_TABLES.EXPORT_ORDER
INTO :TABLE_NAME,:PK
DO
BEGIN
RES = "<table id=""||:TABLE_ID||"">";
SUSPEND;
TABLE_ID = :TABLE_ID + 1;
RES = "<table_name>"||rtrim(:TABLE_NAME)||"</table_name>";
SUSPEND;
RES = "<primary_key>"||rtrim(:PK)||"</primary_key>";
SUSPEND;
TMP = "SELECT ";
FOR SELECT RDB$RELATION_FIELDS.RDB$FIELD_NAME,
coalesce(RDB$FIELDS.RDB$CHARACTER_LENGTH,-1),
coalesce(RDB$RELATION_FIELDS.RDB$NULL_FLAG,0)
FROM RDB$RELATION_FIELDS, RDB$FIELDS
WHERE
RDB$RELATION_FIELDS.RDB$FIELD_SOURCE = RDB$FIELDS.RDB$FIELD_NAME AND
RDB$RELATION_FIELDS.RDB$RELATION_NAME = :TABLE_NAME
ORDER BY RDB$RELATION_FIELDS.RDB$FIELD_POSITION
INTO :FIELD_NAME, :FIELD_CHAR, :FIELD_NULL
DO
begin
if (:FIELD_NULL=0) then
BEGIN
if (:FIELD_CHAR=-1) then
TMP = TMP || """<" || rtrim(:FIELD_NAME) || ">""||coalesce(cast(" || rtrim(:FIELD_NAME) || " as varchar(32)),"""")||""</" || rtrim(:FIELD_NAME) || ">""||";
else
TMP = TMP || """<" || rtrim(:FIELD_NAME) || ">""||coalesce(cast(" || rtrim(:FIELD_NAME) || " as varchar("||:FIELD_CHAR||")),"""")||""</" || rtrim(:FIELD_NAME) || ">""||";
END
else
TMP = TMP || """<" || rtrim(:FIELD_NAME) || ">""||" || rtrim(:FIELD_NAME) || "||""</" || rtrim(:FIELD_NAME) || ">""||";
end
XML = TMP||""""" FROM "||rtrim(:TABLE_NAME) || " WHERE LAST_UPDATED>=(SELECT COALESCE(MAX(SAVEPOINT_DATETIME),""22.11.2004"") FROM APP_SAVEPOINTS WHERE IS_ACTIVE=""Y"")";
RECORD_ID = 1;
FOR EXECUTE STATEMENT :XML INTO :RES DO
begin
RES = "<RECORD id=""||:RECORD_ID||"">"||RES||"</RECORD>";
SUSPEND;
RECORD_ID = :RECORD_ID + 1;
end
RES = "</table>";
SUSPEND;
END
END
Таким образом, мы получаем все изменения, произошедшие в нужных нам таблицах с последней точки сохранения.
Структура полученного XML-файла<export>
<table>
<table_name>Имя таблицы</table_name>
<primary_key>Первичный ключ таблицы</primary_key>
<record>Запись. Поля заранее неизвестны</record>
... все остальные записи
</table>
... все остальные таблицы
</export>
Полученный XML нужно распарсить (это на завтра задание) и сделать insert/update
← →
pasha_golub © (2005-09-12 19:04) [1]Э-э-э, а если диск с БД навернется? вместе с бекапом...
← →
Соловьев © (2005-09-12 19:22) [2]Ав чем прикол XML? Чтобы легче жилось? Тяжело в бинарный файл выгрузить?
Тот же TClientDataSet и FIBPlus...
← →
size=20 (2005-09-12 19:25) [3]
> <primary_key>Первичный ключ таблицы</primary_key>
этот ключ на одной точке 10, а на другой 33 хотя это одна и таже запись. Как ты их найдешь?
что делаешь при удалении записи?
← →
Андрей Жук © (2005-09-12 19:26) [4]Ну бэкапы-то само-собой.
> Тяжело в бинарный файл выгрузить?
Так структура же такого файла заранее неизвестна. Появятся новые поля - ничего менять не придется.
Нашел у себя ошибку - не учитываются удаления.
← →
Андрей Жук © (2005-09-12 19:27) [5]
> этот ключ на одной точке 10, а на другой 33 хотя это
> одна и таже запись.
А как такое может быть?
← →
size=20 (2005-09-12 19:29) [6]
> А как такое может быть?
ну если конечно это генератор
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2005.10.23;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.038 c