如何在SQL触发器中从Opportunity、Communication两表取数插入Comm_link表
可行性分析及问题修正
你当前编写的触发器无法实现需求,存在多处逻辑错误,具体问题如下:
- 插入逻辑永远不生效:你在SELECT查询中用了
INNER JOIN dbo.Comm_Link ON Comm_CommunicationId = CmLi_Comm_CommunicationId,而插入新Communication记录时,Comm_Link里还没有对应关联ID的记录,内连接会直接过滤所有新增数据,最终INSERT语句不会插入任何内容。 - UPDATE场景会触发主键冲突:触发器同时绑定了INSERT和UPDATE事件,就算你删除了上述的内连接逻辑,当Communication记录更新时,触发器会尝试重复插入同一条Comm_Link记录,若CmLi_Comm_CommunicationId为唯一键/主键,会直接报错触发事务回滚。
- 无关联商机的记录会被过滤:
INNER JOIN dbo.opportunity的逻辑会把Comm_OpportunityId为空的Communication记录直接过滤,如果你需要保留无关联商机的记录,需要改为LEFT JOIN。 - 没有重复插入校验:即使是INSERT场景,也可能因为重复触发触发器导致Comm_Link产生冗余重复数据。
修正后的实现代码
推荐使用MERGE语句同时兼容插入、更新两种场景,逻辑更严谨:
CREATE TRIGGER [dbo].[VD_Date_lendemain1] ON [dbo].[Communication] AFTER INSERT, UPDATE AS BEGIN SET NOCOUNT ON; -- 用MERGE同时处理插入和更新场景 MERGE INTO [dbo].[Comm_Link] AS target USING ( SELECT Comm_CreatedBy, Comm_CommunicationId, Comm_ToDateTime, Comm_UpdatedBy, Comm_UpdatedDate, Oppo_PrimaryCompanyId, Oppo_PrimaryPersonId FROM inserted LEFT JOIN dbo.opportunity ON Oppo_OpportunityId = Comm_OpportunityId WHERE Comm_Action = 'Meeting' ) AS source ON (target.CmLi_Comm_CommunicationId = source.Comm_CommunicationId) -- 匹配到则更新(对应UPDATE场景) WHEN MATCHED THEN UPDATE SET CmLi_Comm_UserId = source.Comm_CreatedBy, CmLi_CreatedBy = source.Comm_CreatedBy, CmLi_CreatedDate = source.Comm_ToDateTime, CmLi_UpdatedBy = source.Comm_UpdatedBy, CmLi_UpdatedDate = source.Comm_UpdatedDate, CmLi_Comm_CompanyId = source.Oppo_PrimaryCompanyId, CmLi_Comm_PersonId = source.Oppo_PrimaryPersonId -- 未匹配到则插入(对应INSERT场景) WHEN NOT MATCHED THEN INSERT ( [CmLi_Comm_UserId], [CmLi_Comm_CommunicationId], [CmLi_CreatedBy], [CmLi_CreatedDate], [CmLi_UpdatedBy], [CmLi_UpdatedDate], [CmLi_Comm_CompanyId], [CmLi_Comm_PersonId] ) VALUES ( source.Comm_CreatedBy, source.Comm_CommunicationId, source.Comm_CreatedBy, source.Comm_ToDateTime, source.Comm_UpdatedBy, source.Comm_UpdatedDate, source.Oppo_PrimaryCompanyId, source.Oppo_PrimaryPersonId ); END
如果你的业务要求仅同步有关联商机的沟通记录,把上述代码中的LEFT JOIN dbo.opportunity改为INNER JOIN dbo.opportunity即可。
内容的提问来源于stack exchange,提问作者Pedro8854
相关产品推荐
相关产品推荐

