Salesforce如何查询近4小时无修改的Case记录实现超时提醒
解决方案
现有代码的逻辑问题
你当前编写的SOQL存在3个核心错误,无法满足业务需求:
- 时间判断逻辑完全错误:
LastModifiedDate = TODAY AND HOUR_IN_DAY(LastModifiedDate) > 4筛选的是当天凌晨4点之后修改过的所有记录,既不是滚动的最近4小时窗口,也和「4小时未修改」的需求完全相反;如果调度在凌晨3点执行,该条件会直接返回空结果。 - 缺少所有者类型过滤:没有限定Case的所有者为Queue,会把归属个人用户的Case也纳入查询范围,不符合规则。
- 没有排除无效数据:默认会把已经关闭的Case也查出来,产生无意义的提醒。
正确SOQL写法
Salesforce SOQL原生支持滚动时间窗口的日期字面量,不需要手动计算小时数做判断,也不会有时区偏差。结合业务过滤条件,最终查询逻辑如下:
// 定时类中执行查询的代码块 List<Case> unassignedStaleCases = [ SELECT Id, Subject, LastModifiedDate, OwnerId, Owner.Name FROM Case WHERE // 限定所有者为队列 Owner.Type = 'Queue' // 最后修改时间早于4小时前,即最近4小时无更新 AND LastModifiedDate < N_HOURS_AGO:4 // 排除已关闭的Case AND IsClosed = false // 可选:排除刚创建不足10分钟的Case,避免新记录刚入队就触发提醒 AND CreatedDate < N_MINUTES_AGO:10 // 可选:控制单次查询返回量,避免触及Governor Limit LIMIT 10000 ];
如果你需要在Apex中动态调整时间阈值,也可以先定义时间变量再做绑定,效果和日期字面量一致:
DateTime fourHoursAgo = System.now().addHours(-4); List<Case> unassignedStaleCases = [ SELECT Id, Subject, LastModifiedDate, OwnerId, Owner.Name FROM Case WHERE Owner.Type = 'Queue' AND LastModifiedDate < :fourHoursAgo AND IsClosed = false ];
调度逻辑避坑建议
- 必须做重复提醒拦截:因为调度任务每1小时执行一次,如果不加拦截,同一条滞留在队列的Case会每小时触发一次提醒邮件。建议在Case上新增
Last_Queue_Alert_Time__c日期时间字段,发完提醒后更新该字段为当前时间,查询时追加条件(Last_Queue_Alert_Time__c = NULL OR Last_Queue_Alert_Time__c < N_HOURS_AGO:24),控制同一条Case24小时内最多发一次提醒即可。 - 邮件发送不要在循环中调用
sendEmail方法,把所有待发邮件攒到列表里用批量发送接口,避免触发单日邮件发送限额。 - 不要使用
HOUR_IN_DAY()函数做滚动时间判断,该函数返回的是时间在当天的小时序号(比如14点返回14),只能用于固定时段的筛选,完全无法匹配「最近N小时」的滚动场景。
内容的提问来源于stack exchange,提问作者sForSujit
相关产品推荐
相关产品推荐

