アーカイブ済みの活動をクエリする時はFROM ActivityHistoriesではなくFROM Event ... ALL ROWSを使った方がよさそう #salesforce

あるオブジェクトに関連付いている活動履歴レコードをクエリする場合、SOQLで以下のようにクエリします(関連先のオブジェクトのIDが hogeId の場合)

SELECT
  Id, Subject, Description, StartDateTime, EndDateTime
FROM
  Event
WHERE
  WhatId = :hogeId
ORDER By
  StartDateTime DESC

ただし上記のクエリでは、アーカイブ済み(や削除済み)のレコードは取得できません。

アーカイブ済みのレコードを取得する方法は、調べた限りでは、少なくとも2つの方法がありそうです。

  • FROM ActivityHistories
  • FROM Event … ALL ROWS

パターン① FROM ActivityHistories

親オブジェクトから子(活動履歴)をクエリする方法(リレーションクエリ)です。

SELECT
  Id,
  (
    SELECT
      Id, Subject, Description, StartDateTime, EndDateTime
    FROM
      ActivityHistories
  )
FROM
  Parent__c
WHERE
  ID = :whatId

ちなみに、リレーションクエリを使わずに直接に ActivityHistory をクエリすると以下のエラーになります。

entity type ActivityHistory does not support query.

パターン② FROM Event ALL ROWS

ALL ROWS キーワードを付ける方法です。このキーワードを付けることによって、アーカイブ済み、削除済みのレコードも含めて取得対象になります。
ただし今回は削除済みのレコードは取得したくないので IsDeleted = false を条件に追加しています。

SELECT
  Id, Subject, Description, StartDateTime, EndDateTime
FROM
  Event
WHERE
  WhatId = :hogeId
  AND IsDeleted = false
ORDER By
  StartDateTime DESC
ALL ROWS

2つの書き方の比較

FROM ActivityHistories

  • メリット
    • クエリが1回で済む
  • デメリット
    • 「すべてのデータの参照」権限のないユーザがアクセスする場合、クエリ内部の句では以下の条件をすべて見なしていなければ、エラーになる。
      • WHEREを指定していないこと。
      • LIMIT 500(あるいはそれ以下の値)を指定し、取得レコード数を制限していること。
      • ORDER BYでレコードの取得順を指定する場合、ActivityDate の降順および LastModifiedDate の昇順の順番であること。

FROM Event … ALL ROWS

  • メリット
    • WHERE, LIMIT, ORDER BY に関する検索条件の指定に制限がない(とは言え、WhatIdで関連先オブジェクトを絞ったり、一般的なガバナ制限には気をつける必要はあります)
  • デメリット(運用上はデメリットにはならないと思いますが…)
    • ALL ROWS キーワードは開発者コンソール(Query Editor)では利用できない(Apexからのみ利用可)

ActivityHistoriesを使ったリレーションクエリの場合、デメリットが大きいんですよね。
現実問題、「すべてのデータの参照」権限のないユーザが利用することは普通のケースだと思います。というわけで、上記のルールの上でがんばるよりは、おとなしく FROM Event … ALL ROWS を使った方がよさそう、という結論に至りました。

ちなみに、制限に違反していると、以下のようなエラーに遭遇します。

  • LIMIT指定がない場合

There is an implementation restriction on ActivityHistories. When you query this relationship, security evaluation is implemented for users who don’t have administrator permissions, and you must specify a LIMIT with a maximum of 500

  • ORDER BY の指定が想定外場合

There is an implementation restriction on ActivityHistories. When you query this relationship, security evaluation is implemented for users who don’t have administrator permissions, and you must use a specific sort order: ActivityDate DESC, LastModifiedDate DESC

このあたり、以下のURLに書かれていることなんですが、「次の制約は、パフォーマンスの問題を回避するのに役立ちます。」みたいな言い回しよりも、はっきりとエラーになる旨を書いておいてほしい…。

developer.salesforce.com