7

我正在查询 ActivityHistory,看来您只能将其作为 SUBQUERY 的对象来查询其他对象。没关系 - 我将查询更改为针对 Account 对象进行查询,并在子查询中使用 ActivityHistory。似乎工作正常。但是在测试中,我发现了一个 ActivityHistory 子查询返回超过 200 个结果的情况。我开始收到此错误:

    FATAL_ERROR|System.QueryException:实体类型 ActivityHistory 不支持查询

...在调试日志中。这似乎只是一个帐户在 ActivityHistory 对象中有超过 199 个相关条目的问题。为了查看这是否是原因,我尝试在子查询中放置一个 LIMIT 199 和一个 LIMIT 200 子句。果然,当我使用 199(或更低)时,它工作正常。使用 200(或更高)会导致上述错误。

我的代码如下。需要注意的一件事是查询在 FOR 循环中。关于为什么它会为 LIMIT 子句的高值产生错误的一个理论是,也许 200 是 FOR 循环将查询分批成单独块的点 - 也许第二个块不符合“子查询”的条件(因为它是单独运行的?) - SalesForce 不喜欢这样。

哦,还有一件事:相同的代码似乎在匿名 Apex 编辑器中运行良好(尽管我必须进行一些修改 - 用显式值替换内联变量)。奇怪的是匿名编辑对此非常满意,但 SFDC 服务器不喜欢它。

无论如何,我要进行更多故障排除。有人有任何见解吗?

谢谢!

代码:

    // ActivityHistory 的帐户
    for (Account a : [ // 不能直接查询 ActivityHistory;只能在针对另一个对象类型的子查询中
        选择
             ID
            ,姓名
            ,( 选择
                    活动日期
                   ,活动类型
                   ,CRM_Meeting_Type__c
                   ,描述
                   ,CreatedBy.Name
                   ,地位
                   ,什么ID
                来自活动历史
                WHERE ActivityType IN :included_activity_history_types
                //限制 200
            )
        FROM Account WHERE Id = :accountId
    ]) {
     for (ActivityHistory ah : a.ActivityHistory) {
        if ( ah.WhatId==null ) { 继续; } // 跳过添加没有 WhatId 的活动

        if (((string)ah.WhatId).startsWith('001')) { // 只添加 ActivityHistory 直接绑定到一个 Account (上面的查询也拉回了相关 Oppty 上的所有 ActivityHistory)
            活动.add(新的ActivityWrapper(ah));
        }
     }
    }
4

2 回答 2

7

好问题;我不完全确定为什么它会在 Execute Anonymous 中工作,而不是在您的 Apex 课程中。

不过,我确实有一些建议。我发现从for循环中分离出 SOQL 查询很有帮助,然后使用该getSObjects方法获取返回的子查询数据。使用这种方法,我已经成功地在一个 Apex 类中检索了 200 多条 ActivityHistory 记录。

注意:一个区别(你的代码和我之前的工作方式之间)是我没有在 ActivityHistories WHERE 子句中按 ActivityType 过滤。所以,如果下面的代码抛出相同的错误,我会检查下一个。

List<Account> AccountsWithActivityHistories = [  
    // you can't query ActivityHistory directly; only in a subquery against another object type
    SELECT
         Id
        ,Name
        ,( SELECT
                ActivityDate
               ,ActivityType
               ,CRM_Meeting_Type__c
               ,Description
               ,CreatedBy.Name
               ,Status
               ,WhatId
            FROM ActivityHistories
            WHERE ActivityType IN :included_activity_history_types
            //LIMIT 200
        )
    FROM Account WHERE Id = :accountId
];

// ActivityHistories on Account
for (Account a : AccountsWithActivityHistories) {
  for (ActivityHistory ah : a.getSObjects('ActivityHistories')) {
    // skip adding activities without a WhatId
    if ( ah.WhatId==null ) { continue; }  

    if (((string)ah.WhatId).startsWith('001')) { 
        // only add ActivityHistory's tied directly to an Account 
        // (the query above pulls back all ActivityHistory's on related Oppty's as well)
        activities.add(new ActivityWrapper(ah));
    }
  }
}
于 2012-06-08T15:19:45.147 回答
2

这可能已经过时了,但我遇到了这个问题,想把我在另一个论坛上找到的解决方案扔出去。

activityhistory 对象只是一个设置为“已关闭”的任务或事件。因此,您可以查询位于“活动历史”后面的对象并将其附加到新联系人或潜在客户下方,这会将相同的对象存储为新的“活动历史”对象。

list<Task> activityHistory = [SELECT Id,WhoId FROM Task t WHERE t.WhoId = 'randomID' and t.Status != 'Open'];

for(Task currentAH : activityHistory){
    system.debug(currentAH.Id);
}

上面的代码带回了所有“任务”活动历史对象,并允许我使用 WhoId 将它们重新分配给另一个联系人/潜在客户。

于 2015-01-13T02:36:37.660 回答