2012-06-07 7 views
6

Pytam ActivityHistory, i wydaje się, że można go tylko zapytać jako obiekt PODKŁADU przed jakimś innym obiektem. To w porządku - zmieniłem zapytanie w zapytanie na obiekt konta, z ActivityHistory w podzapytaniu. Wydawało się działać poprawnie. Ale podczas testowania znalazłem przypadek, w którym podkwerenda ActivityHistory zwrócił WIĘCEJ niż 200 wyników. I zaczęła się ten błąd: Problem z SOQL podczas sprawdzania historii ActivityHi jako podkwerendy.

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

... w dziennikach debugowania. Wydaje się, że jest to tylko kwestia, w której Konto ma ponad 199 powiązanych wpisów w obiekcie ActivityHistory. Aby sprawdzić, czy to była przyczyna, spróbowałem umieścić klauzulę LIMIT 199 i LIMIT 200 w podzapytaniu. Oczywiście, kiedy używam 199 (lub cokolwiek niższego), działa dobrze. Użycie 200 (lub cokolwiek wyżej) powoduje błąd powyżej.

Mój kod jest poniżej. Należy pamiętać, że zapytanie jest w pętli FOR. Jedną z teorii, która wyjaśnia, dlaczego generuje błąd dla wysokich wartości klauzuli LIMIT, jest to, że prawdopodobnie 200 jest punktem, w którym pętla FOR zgłasza zapytanie w oddzielnych porcjach - być może druga część nie kwalifikuje się jako "podkwerenda" (skoro działa osobno?) - a SalesForce tego nie lubi.

Aha, i jeszcze jedno: ten sam kod wydaje się działać dobrze w edytorze Anonymous Apex (chociaż musiałem wprowadzić kilka modyfikacji - zastępując zmienne śródliniowe wyraźnymi wartościami). Dziwne, że edytor anon jest z niego całkowicie zadowolony, ale serwery SFDC tego nie lubią.

W każdym razie, mam zamiar zrobić więcej rozwiązywania problemów. Ktoś ma jakieś spostrzeżenia?

Dzięki!

Kod:

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

Odpowiedz

7

Wielkie pytanie; Nie jestem do końca pewien, dlaczego działał w Execute Anonymous, ale nie w klasie Apex.

Jednak mam pewne zalecenia. Odkryłem, że pomocne jest podzielenie zapytań SOQL z pętli for, a następnie skorzystanie z metody getSObjects, aby uzyskać dane podzapytania, które zostały zwrócone. Korzystając z tej metody, udało mi się pobrać ponad 200 rekordów ActivityHistory w klasie Apex.

Uwaga: jedną różnicą (między kodem a poprzednim sposobem, w jaki działałem) jest to, że nie filtrowałem według ActivityType w klasie ActivityHistories WHERE. Tak więc, jeśli poniższy kod zgłasza ten sam błąd, sprawdziłbym to później.

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

To może być nieaktualne, ale trafiłem na ten problem i chciałem rzucić moje rozwiązanie, które znalazłem na innym forum.

Obiekt activityhistory jest tylko zadaniem lub zdarzeniem ustawionym na "Closed". Dlatego możesz zapytać o obiekt, który siedzi za "Historią aktywności" i dołączyć go pod nowym kontaktem lub ołowiu, a to będzie przechowywać ten sam obiekt, co nowy obiekt "Historia aktywności".

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

Powyższy kod sprowadzony wszystkie „zadanie” aktywność historia obiektów i pozwala mi reparent je za pomocą WhoId do innego kontaktu/ołowiu.

Powiązane problemy