Loading
Salesforce から送信されるメールは、承認済ドメインからのみとなります続きを読む

SOQL クエリでの offset の上限 2000 件に対する回避策

公開日: Oct 13, 2022
説明
※この記事は英語版を翻訳しており、一部機械翻訳を含むため内容は後日更新される可能性があります。最新の内容は英語版を参照してください。表示言語は画面右下の言語名から切り替えられます。

標準のクエリのページ分割を使用すると、「The maximum offset is 2,000 rows.Requesting an offset greater than 2,000 will result in a NUMBER_OUTSIDE_VALID_RANGE error. (最大オフセットは 2,000 行です。2,000 を超えるオフセットを要求すると、NUMBER_OUTSIDE_VALID_RANGE エラーが発生します。)」というエラーが発生します。制限はハードコーディングされているため増やすことはできませんが、推奨される回避策は次のとおりです。
解決策

一度にすべてのデータを取得する場合に適切な手段は QueryMore です。ウェブサイトやポータルサイトのようなページ設定では、何らかの値で並べ替えてから検索条件を使用します。ページ設定をより簡単にするには、カーディナリティが高く、一意の値が多い項目を使用することをお勧めします。

CreatedDate や ID で並べ替えている場合、最初のクエリは次のようになります。

SELECT Id, Name, CreatedDate FROM Account ORDER BY CreatedDate LIMIT 2000

この時点で、2000 件のレコードを取得したことになります。2,000 番目の CreatedDate または ID (並べ替える項目によって異なる) を取り、次のクエリに追加します。

SELECT Id, Name, CreatedDate FROM Account WHERE CreatedDate > "Last-Returned-Created-Date" ORDER BY CreatedDate LIMIT 2000

そして、次の 2,000 件のレコードを取得します。必要に応じて同じ手順を繰り返します。1 ページ前に戻りたい場合は順序を逆にします。ただし、次のように結果も逆にする必要があります。

SELECT Id, Name, CreatedDate FROM Account WHERE CreatedDate < "First-Returned-Created-Date" ORDER BY CreatedDate DESC LIMIT 2000

より良いパフォーマンスを得るためには、「getUpdated()」と「getDeleted()」(SOAP API 複製) を使用してデータを定期的に更新するクライアント側のキャッシングを検討します。

いずれにせよ、最初は 50,000 番目まで「行く」のではなく、自分の足で歩く必要があります。この点ではキャッシュが最大の効果を発揮するため、大規模なデータセットをお持ちの方はぜひご検討ください。

また、上記の方法でレコードをすばやく 1 つずつチェックするためのカスタム Web サービスを次のように記述することもできます。

global webservice Id findOffset(String query) { 
    SObject[] results = Database.query(query); 
    return results[results.size()-1].Id; 
}
Apex コードのレコード数は最大 50,000 件のため、このテクニックを使えば一度に 50,000 行をスキップでき、総効率は 50,000 行につき 1 API コール、さらにページの結果を与える最終クエリに 1 コールとなります。

関連リソース: SOQL における OFFSET
ナレッジ記事番号

000387840

 
読み込み中
Salesforce Help | Article