【发布时间】:2020-05-07 17:01:46
【问题描述】:
在这种情况下,我有两张桌子。一个是我的“热同步”表,它是从我的 Salesforce 组织到 Postgres 表的近实时双向同步数据。随着源系统 (Salesforce) 中的数据发生变化,它会更新 Postgres 上的该表。
在 Postgres 的这张表上,我有一个运行一些逻辑的触发器。它基本上检查触发它的记录是否具有满足某些业务逻辑的发送日期,将该行复制到另一个架构/表中以“归档”它。
这一切都很好。
然而,我需要做的是,一旦将这一行复制到另一个表中,我需要更新记录热同步表的状态。由于它是双向的,这将允许 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 应该只更新源表上的一条记录吗?
尝试确保触发器不会再次触发,更新语句会导致一些我不期望的递归循环。
我担心的是:
- 记录已更新
- 触发器触发并将记录插入存档表
- 更新在源表上运行以更新 new.id 的记录
- 此更新导致触发器再次运行。由于
on conflict,插入会失败,但更新会再次运行,等等。
原始触发器被触发AFTER INSERT/UPDATE。
触发:
CREATE TRIGGER archivelogic_firetrigger
AFTER INSERT OR UPDATE
ON salesforce.et4ae5__individualemailresult__c
FOR EACH ROW
EXECUTE PROCEDURE salesforce.archivelogicfunc();
更新:
我在触发器中添加了WHEN 条件。它似乎适用于基本测试,但如果有建议,它愿意接受任何其他建议。
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();
【问题讨论】:
标签: postgresql database-trigger