查询ActivityHi故事作为子查询时出现SOQL问题。

时间:2012-06-07 21:00:24

标签: subquery salesforce soql

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

    FATAL_ERROR|System.QueryException: entity type ActivityHistory does not support query

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

我的代码如下。需要注意的一点是查询是在FOR循环中。我得到的一个理论是,为什么它为LIMIT子句的高值产生错误,可能200是FOR循环将查询批处理为单独的块的点 - 也许第二个块不符合'子查询'的条件(因为它是单独运行的?) - 并且SalesForce不喜欢它。

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

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

谢谢!

代码:

    //  ActivityHistory's on Account
    for (Account a : [  //  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
    ]) {
     for (ActivityHistory ah : a.ActivityHistories) {
        if ( ah.WhatId==null ) { continue; }  //  skip adding activities without a WhatId

        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));
        }
     }
    }

2 个答案:

答案 0 :(得分: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));
    }
  }
}

答案 1 :(得分: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将其重新显示给另一个联系人/潜在客户。