В этом сценарии у меня две таблицы. Одна из них - моя таблица «горячей синхронизации c», которая представляет собой двунаправленную синхронизацию c данных из моей организации Salesforce с таблицей Postgres почти в реальном времени. По мере изменения данных в исходной системе (Salesforce) эта таблица обновляется на Postgres.
В этой таблице в Postgres у меня есть триггер, который запускает некоторые logi c. Он в основном проверяет, имеет ли инициирующая запись дату отправки, которая соответствует некоторому бизнес-логу c, копирует эту строку в другую схему / таблицу, чтобы «заархивировать» ее.
Все это работает нормально.
Что мне нужно сделать, так это после того, как эта строка будет скопирована в другую таблицу, мне нужно обновить статус таблицы горячей синхронизации c записи. Поскольку он двунаправленный, это позволит данным в Salesforce отразить изменения, которые я вношу со стороны Postgres.
Могу ли я разместить этот оператор обновления в исходном триггере или это вызовет рекурсию вопросы?
CREATE FUNCTION salesforce.archivelogicfunc()
RETURNS trigger
LANGUAGE 'plpgsql'
COST 100
VOLATILE NOT LEAKPROOF
AS $BODY$ BEGIN
IF (DATE(NEW.et4ae5__datesent__c) < NOW() - INTERVAL '180 days'
AND DATE(NEW.et4ae5__datesent__c) > NOW() - INTERVAL '540 days')
THEN
INSERT INTO archive.individualemailresult__c
(dateopened__c,
numberoftotalclicks__c,
datebounced__c,
fromname__c,
hardbounce__c,
fromaddress__c,
softbounce__c,
name,
lastmodifieddate,
opened__c,
ownerid,
subjectline__c,
isdeleted,
contact__c,
systemmodstamp,
lastmodifiedbyid,
datesent__c,
dateunsubscribed__c,
createddate,
createdbyid,
lead__c,
tracking_as_of__c,
numberofuniqueclicks__c,
senddefinition__c,
mergeid__c,
triggeredsenddefinition__c,
sfid,
id,
_hc_lastop,
_hc_err,
isarchived)
VALUES
(NEW.et4ae5__dateopened__c,
NEW.et4ae5__numberoftotalclicks__c,
NEW.et4ae5__datebounced__c,
NEW.et4ae5__fromname__c,
NEW.et4ae5__hardbounce__c,
NEW.et4ae5__fromaddress__c,
NEW.et4ae5__softbounce__c,
NEW.name,
NEW.lastmodifieddate,
NEW.et4ae5__opened__c,
NEW.ownerid,
NEW.et4ae5__subjectline__c,
NEW.isdeleted,
NEW.et4ae5__contact__c,
NEW.systemmodstamp,
NEW.lastmodifiedbyid,
NEW.et4ae5__datesent__c,
NEW.et4ae5__dateunsubscribed__c,
NEW.createddate,
NEW.createdbyid,
NEW.et4ae5__lead__c,
NEW.et4ae5__tracking_as_of__c,
NEW.et4ae5__numberofuniqueclicks__c,
NEW.et4ae5__senddefinition__c,
NEW.et4ae5__mergeid__c,
NEW.et4ae5__triggeredsenddefinition__c,
NEW.sfid,
NEW.id,
NEW._hc_lastop,
NEW._hc_err,
NEW.isarchived__c)
ON CONFLICT (id)
DO NOTHING;
-- Update SF to reflect the archive
UPDATE salesforce."et4ae5__individualemailresult__c" SET isarchived__c = true, isdeleted = true WHERE id = NEW.id;
END IF;
RETURN NULL;
END;
$BODY$;
ALTER FUNCTION salesforce.archivelogicfunc()
OWNER TO ....;
Насколько я понимаю, NEW.*
будет содержать только те строки, которые изначально вызвали срабатывание триггера. Следовательно, если мой триггер сработал для одной записи, оператор обновления NEW.id
должен обновлять только одну запись в исходной таблице? какой-то рекурсивный l oop, которого я не ожидал.
Меня беспокоит:
- Запись обновлена
- Триггер срабатывает и вставляет запись в архивную таблицу
- В исходной таблице выполняется обновление для обновления записи для new.id
- Это обновление вызывает повторный запуск триггера. Вставка не удалась из-за
on conflict
, но затем обновление запустилось бы снова, и снова et c ..
Срабатывает исходный триггер AFTER INSERT/UPDATE
.
ТРИГГЕР:
CREATE TRIGGER archivelogic_firetrigger
AFTER INSERT OR UPDATE
ON salesforce.et4ae5__individualemailresult__c
FOR EACH ROW
EXECUTE PROCEDURE salesforce.archivelogicfunc();
ОБНОВЛЕНИЕ: Я добавил в свой триггер условие WHEN
. Похоже, что он работал на базовом c тесте, но готов принять любой другой совет, если предложат.
CREATE TRIGGER archivelogic_firetrigger
AFTER INSERT OR UPDATE
ON salesforce.et4ae5__individualemailresult__c
FOR EACH ROW
WHEN (pg_trigger_depth() = 0) // <-- Added to prevent recursion
EXECUTE PROCEDURE salesforce.archivelogicfunc();