如何编写SQL Server触发器实现多表数据条件插入至报表表?
解决方案:SQL Server触发器实现自动插入
核心结论
完全可以实现符合条件的新增数据自动插入到RPT.SPC.Report表,不需要额外创建表存储最后插入的CreatedDate,利用SQL Server触发器自带的inserted虚拟表就能精准筛选刚新增的目标记录。
触发器实现代码
CREATE TRIGGER TR_DefectDetail_Insert_SPCReport ON PRD.dbo.DefectDetail AFTER INSERT AS BEGIN SET NOCOUNT ON; -- 阻止返回受影响行数的消息,避免干扰调用方 -- 仅处理符合QualityType=1的新增记录 INSERT INTO RPT.SPC.Report ( QualityDataID, LineID, LineName, ProgramName, ReportDate, ReportHour, PartNo, Location, DefectCode, ResultGUID, Code, CavityIndex ) SELECT i.QualityDataID, qd.LineID, qd.LineName, qd.ProgramName, qd.ReportDate, qd.ReportHour, i.PartNo, i.Location, i.DefectCode, i.ResultGUID, ar.Code, i.PCBCavityIndex FROM inserted i -- 仅触发本次新增的记录,避免全表扫描 LEFT JOIN PRD.dbo.Quality qd ON qd.QualityID = i.QualityDataID LEFT JOIN PRD.dbo.Result ar ON i.ResultGUID = ar.ResultGUID WHERE i.QualityType = 1 -- 如果CreatedDate是datetime类型,确保不是无效值(可选,根据实际业务调整) AND i.CreatedDate IS NOT NULL; END; GO
关键细节说明
inserted虚拟表的作用
触发器触发时,inserted表会临时存储本次事务中新增的所有DefectDetail记录,直接基于这个表查询,既能精准获取待插入的目标数据,又避免了全表扫描DefectDetail,性能远优于用时间戳筛选。CreatedDate字段的处理- 原查询中
dd.CreatedDate > ''的写法存在问题:如果CreatedDate是datetime类型,空字符串会被隐式转换为1900-01-01,实际意义不大。 - 触发器中直接用
inserted表的CreatedDate做非空判断即可(如果业务要求必须有有效创建时间),不需要额外存储最后插入时间——因为inserted本身就是本次新增的记录集合。
- 原查询中
其他注意事项
- 去掉了原查询中的
WITH(NOLOCK):触发器运行在事务内,NOLOCK可能导致读取未提交数据,若业务上Quality和Result表的数据是在插入DefectDetail前已提交,无需加NOLOCK。 - 确保
RPT.SPC.Report的字段与查询结果的字段类型、长度完全匹配,避免插入失败。
- 去掉了原查询中的
内容的提问来源于stack exchange,提问作者Ramesh
相关产品推荐
相关产品推荐

