РЕЗЮМЕ ЗАДАЧИ
Я должен написать триггеры генерации операторов I / U / D для самодельной системы двунаправленной репликации в стиле Bucardo / симметричногоDS между группами узлов Sybase ADS и Postgresql 11, используя триггеры BEFORE на любых Postgresql и Sybase DB, которые создают Команды вставки / обновления / удаления на основе команды, введенной в реплицирующую исходную таблицу: например, INSERT INTO PERSON (first_name,last_name,gender,age,ethnicity) Values ('John','Doe','M',42,'C')
и манипулировать ими в соответствующем операторе Insert и UPDATE, получая значения OLD и NEW для динамического создания оператора UPDATE, а также значения OLD для создания команды DELETE, которые все запускаются для каждой команды в пункте назначения через некоторый интервал ,
Я знаю, что это сложно, и никто не делает этого, но это для работы, и у меня нет других вариантов, и я не могу возразить, чтобы предложить другое решение. У меня нет других товарищей по команде или человеческих ресурсов, которые могли бы помочь вне SO, и что-то вроде Codementors, что было не так полезно. Моя идея / стратегия состоит в том, чтобы копировать части bucardo / SymmetricDS при вставке значений OLD и NEW для генерации оператора / команды для выполнения в месте назначения. Прямо сейчас я делаю снимок всей таблицы в CSV, в отличие от выполнения отдельной командой, но с помощью команды и циклического перемещения по таблице, которая генерирует и сохраняет команды, сделает работу намного проще.
Одна большая проблема заключается в том, что они приходят из Sybase ADS и имеют смешанную структуру Key / Index (многие таблицы не имеют PK) и отражают это в Postgresql, поэтому я пытаюсь написать операторы без PK или все столбцы команды, чтобы обойти таблицы no-pk. Они также будут реплицировать только определенные столбцы для определенных таблиц, поэтому у меня есть столбец в таблице для вставки имен столбцов, разделенных символом ';' а затем разбить его на массив и связать имена столбцов со значениями для каждого оператора, чтобы сгенерировать полную команду для I / U / D, надеюсь. Я открыт для других стратегий, но это большой сольный проект, и я с большим трудом справился с ним.
В основном я из ДБА и имею некоторый опыт программирования с основами, поэтому я в основном псевдокодирую каждую основную последовательность, ищу синтаксис по частям и настраиваюсь по мере появления или сталкиваюсь с неспособностью языка. Я благодарен за любую помощь, оказанную, поскольку я становлюсь немного отчаянным и обескураженным.
ЧТО Я ПОПЫТАЛ
Я должен сделать это для Sybase ADS и Postgresql, но этот вопрос по сути вопрос ADS, поскольку он более сложный и старый.
Наличие одной таблицы «Журнал», которая отслеживает изменения строк для каждой из реплицируемых таблиц и записей и в конечном итоге динамически генерирует команду, является целью для обеих платформ. Я пытаюсь сделать триггер заявления вроде:
CREATE TRIGGER PERSON_INSERT
ON PERSON
BEFORE
INSERT
BEGIN
INSERT INTO Backlog (SourceTableID, TriggerType, Status, CreateTimeDate, NewValues) select ID, 'INSERT','READY', NOW(),''first_name';'last_name';'gender';'age';'ethnicity'' from __new;
END;
CREATE TRIGGER PERSON_UPDATE
ON PERSON
BEFORE
UPDATE
BEGIN
INSERT INTO Backlog (SourceTableID, TriggerType, Status, CreateTimeDate, NewValues) select ID, 'U','UPDATE','READY', NOW(),''first_name';'last_name';'gender';'age';'ethnicity'' from __new;
UPDATE Backlog SET OldValues=select ''first_name';'last_name';'gender';'age';'ethnicity'' from __old where SourceTableID=select ID from __old;
END;
CREATE TRIGGER PERSON_DELETE
ON PERSON
BEFORE
DELETE
BEGIN
INSERT INTO Backlog (SourceTableID, TriggerType, Status, CreateTimeDate, OldValues) select ID, 'D','DELETE','READY', NOW(),''first_name';'last_name';'gender';'age';'ethnicity'' from __old;
END;
но я бы хотел, чтобы "'' first_name ';" last_name ";" пол ";" возраст ";" этническая принадлежность "" "пришли из другой таблицы в качестве значения, чтобы сделать его динамическим, поскольку несколько таблиц будут записывать свое значение и информация выписки в единую таблицу журнала. Затем его можно преобразовать в переменную, а затем, вероятно, разделить, чтобы связать с соответствующими значениями, чтобы можно было создавать операторы IUD, которые будут выполняться по месту назначения по одному.
ПОПЫТКА НЕПОЛНОГО ОБРАЗЕЦ КОДА ТРИГГЕРА
CREATE TRIGGER PERSON_INSERT
ON PERSON
BEFORE
INSERT
BEGIN
--Declare @Columns string
--@Columns=select Columns from metatable where tablename='PERSON'
--String Split(@Columns,';') into array to correspond to new and old VALUES
--@NewValues=@['@Columns='+NEW.@Columns+'']
INSERT INTO Backlog (SourceTableID, TriggerType, Status, CreateTimeDate, NewValues) select ID, 'INSERT','READY', NOW(),''first_name';'last_name';'gender';'age';'ethnicity'' from __new;
END;
CREATE TRIGGER PERSON_UPDATE
ON PERSON
BEFORE
UPDATE
BEGIN
--Declare @Columns string
--@Columns=select Columns from metatable where tablename='PERSON'
--String Split(@Columns,';') into array to correspond to new and old VALUES
--@NewValues=@['@Columns='+NEW.@Columns+'']
--@OldValues=@['@Columns='+OLD.@Columns+'']
INSERT INTO Backlog (SourceTableID, TriggerType, Status, CreateTimeDate, NewValues) select ID, 'U','UPDATE','READY', NOW(),''first_name';'last_name';'gender';'age';'ethnicity'' from __new;
UPDATE Backlog SET OldValues=select ''first_name';'last_name';'gender';'age';'ethnicity'' from __old where SourceTableID=select ID from __old;
END;
CREATE TRIGGER PERSON_DELETE
ON PERSON
BEFORE
DELETE
BEGIN
--Declare @Columns string
--@Columns=select Columns from metatable where tablename='PERSON'
--String Split(@Columns,',') into array to correspond to new and old VALUES
--@OldValues=@['@Columns='+OLD.@Columns+'']
INSERT INTO Backlog (SourceTableID, TriggerType, Status, CreateTimeDate, OldValues) select ID, 'D','DELETE','READY', NOW(),''first_name';'last_name';'gender';'age';'ethnicity'' from __old;
END;
ЗАКЛЮЧЕНИЕ
Для каждой вставленной, обновленной или удаленной строки; в столбце COMMAND в таблице журнала я пытаюсь сгенерировать соответствующий оператор типа INSERT INTO PERSON ('+ @ Columns +') VALUES ('+ @ NewValues +') 'или UPDATE или DELETE. Затем служба Foreach будет выполнять каждое значение команды, упорядоченное по времени создания, в качестве основной службы репликации.
Чтобы было ясно, я пытаюсь, чтобы мой примерный триггер кода записывал все старые значения и новые значения в столбец динамическим способом без жесткого кодирования столбцов в каждом триггере, поскольку он будет использоваться для нескольких таблиц, и записи значений в один столбец, разделенный запятой или точкой с запятой.
Еще большее желание или цель заключается в том, чтобы найти способ сохранить / написать каждую команду IUD и затем запустить ее на сервере подписчика. Базы данных postgresql и платформы Sybase, поэтому я делаю свою собственную репликацию из журнала