記事公開日
最終更新日
【Power Automate】Dataverseのレコード件数を正しく数える

こんにちは。DXソリューション営業本部の吾妻です。
Dataverseテーブルにデータを格納したり、削除したりするようなPower Automateクラウドフローを実装する際に、データの整合性を確認する第一歩として、テーブルに格納されているレコードの総数を取得しなければならないことがあるかと思います。
行をカウントする処理自体は、要件としては複雑なものではないのですが、Dataverse Web API側の制限、コネクタ側の制限、クラウドフローでの制限、HTTPリクエストの制限といった、様々な制約事項を考慮しなければなりません。特に、レコード数が多いテーブルを対象とする場合には、これらの制限に抵触しやすくなります。
この記事では、レコード数をカウントする実装の具体例をもとに、注意すべきポイントをご紹介していきたいと思います。
レコード件数を取得する方法
Dataverseにおいて、レコード件数(テーブルの行数)を取得するための方法として、以下の6種類があります。それぞれの設定方法と、取得できる件数の上限を、以下の表に示します。
項目 | 件数の制約 |
①Dataverseコネクタ | 5,000件以下 |
②Dataverseコネクタで「改ページ」「閾値」を設定 | 100,000件以下 |
③Dataverseコネクタで「ページングCookie」を設定 | - |
④Dataverse Web APIでクエリ「$count」を設定 | 5,000件以下 |
⑤Dataverse Web APIでクエリ「fetchXml」を設定 | 50,000件以下 |
⑥Dataverseの「RetrieveTotalRecordCount」関数を実行 | - |
Dataverseテーブルにどのくらいレコードが存在するか不明な場合(何十万件もレコードが存在し得るとき)に、レコード数をカウントするクラウドフローを、最もシンプルに実装できるのは、⑥の「RetrieveTotalRecordCount」関数を呼び出す方法です。ただし、この方法で得られる件数は、関数を呼び出したタイミングでのリアルタイムな値ではありません。
件数を取得するだけでなく、別のデータベースにレコードを連携したり、複数のレコードをもとに集計したりする必要がある場合には、③のDataverseコネクタとページングCookieを組み合わせる方法で実装します。③については、クラウドフローのサンプルを含むソリューションパッケージを、解説とともに載せておくので、参考にしてみてください。
実装例と解説
それでは、Dataverseテーブルの行数を取得するための6種類の実装を、詳しく見ていきましょう。
これからご紹介する実装例では、Dataverseに用意した「Member」テーブル(スキーマ名はya_Member、論理名はya_member)のレコード件数を取得します。101,000件のダミーデータを格納しておき、③、⑥の方法で、10万件超のレコードが格納されているテーブルでも件数をカウントできるか確認しようと思います。

①Dataverseコネクタ
シンプルに、Dataverseコネクタの「行を一覧にする」アクションで行を取得して、その行数を、length関数で取得する方法です。Fetch XML クエリなどのパラメーターを指定してページング処理を実装しない限り、(Dataverse Web APIでの$countクエリの仕様により)一覧として取得できる「行数」の上限は5,000行なので、カウントできる行数の上限も5,000行となります。
また、「行のフィルター」にODataクエリを指定しているのは、クラウドフローを保存した際に「OData フィルター クエリを使用するようにアクション '行を一覧にする' を更新すると、フローのパフォーマンスを向上させることができます」という警告が表示されるのを防ぐためです。「createdon(作成日)」などのシステム列をクエリに指定することで、列の接頭辞を気にせずパラメーターを定義することができます。

②Dataverseコネクタで「改ページ」「閾値」を設定
Dataverseコネクタの「行を一覧にする」アクションで行を取得する際に、改ページ・閾値のパラメーターを設定して、取得できた行数を、length関数で取得する方法です。①と異なり、5,000行を超えて取得することができますが、100,000行が取得・カウントできる行数の上限となります。この、100,000行の上限は、クラウドフロー側の仕様(ページ付けされた項目)によります。また、有償版ライセンスではなくMicrosoft 365の範囲内でPower Automateを利用している場合は、パフォーマンスプロファイルが「低」になるので、5,000行が上限になります。


③Dataverseコネクタで「ページングCookie」を設定
Dataverseコネクタの「行を一覧にする」アクションで行を取得する際に、「Fetch Xml クエリ」にページングCookieを設定して、取得できた行数を、length関数で取得する方法です。先頭のfetchタグの最後にページングCookieを設定していること、改ページや閾値の設定をしないことの2点が、②とは異なります。また、①、②と異なり、100,000行を超えて取得することができます。
「行を一覧にする」アクションでこのパラメーターを指定する場合には、「Fetch Xml クエリ」以外の「行のフィルター」などのパラメーターも同時に指定してしまうと、期待通りのページング結果を得られないことがあります。
公式ドキュメントには、取得できる上限の件数は明記されておらず、アクションやDataverse Web APIでの制限はありませんが、クラウドフローの継続時間の制限があるので、無制限に取得し続けることはできません。とはいえ、カウントに30日要するような規模のテーブルは現実的に使うことはないので、大抵のシナリオではこの方法で対応できるはずです。また、行数をカウントするだけでなく、各行に対して更新をかけたりリレーション先のレコードを拾ってきたりして、Dataverseにアクセスするようなアクションをたくさん配置している場合には、Power Platform要求の制限に引っ掛かることがあるので、ループの中で待ち時間を挟んだり、クラウドフロー(およびそのフローを実行するユーザー)を分割したりといった工夫が必要になることがあります。
また、この実装ではDo untilアクションを利用していますが、アクションの設定「Count」「Timeout」の既定値がそれぞれ「60」「PT1H」となっているので、レコード数でいうと60×5,000=300,000件、継続時間でいうと1時間のいずれかに達した時点で繰り返し処理が終了してしまいます。そのため、これらの条件を超えてレコードを取得することが想定される場合には、途中で繰り返し処理が終了して全量取得できない事態を防ぐために、予め設定を変更しておく必要があります。特に「Timeout」の設定方法が分かりにくいですが、ISO 8601 duration (継続時間) formatに基づいて指定するので、1か月なら「P1M」、30分なら「PT30M」のように入力します。
ちなみに、「Fetch Xml クエリ」パラメーターに指定する文字列は、GETリクエストとしてDataverse Web APIに送信されることから、「Fetch Xml クエリ」を含めたURLの長さは32,768文字までという制限があります。図のように「すべての列を取得する設定(all-attributesタグ)」にするのではなく、「列を個別に取得する設定(attributeタグ)」にした場合や、フィルター条件を追記した場合は、クエリの文字数が増えがちなので、注意が必要です。文字数が多いクエリをどうしても利用したいときには、バッチリクエスト(バッチ操作/バッチ要求とも呼ばれます)に置き換えることで、FetchXMLを定義する場所を、GETリクエストのURLからPOSTリクエストの本文に移すことができるので、65,536文字まで上限を増やすことができます。ただし、行を一覧にするアクションのままでは利用できないので、HTTP要求を呼び出すアクションなど、別のアクションに置き換える必要があります。
テーブルとクラウドフローのサンプルをまとめたソリューションパッケージをこちらに載せておきます。ご参考まで。

④Dataverse Web APIでクエリ「$count」を設定
「Microsoft Entra ID 付きの HTTP」コネクタの「HTTP 要求を呼び出す」アクションで、クエリ「$count」を設定してDataverse Web APIを呼び出す方法です。 ①と同様に、Dataverse Web APIでの仕様によって、カウントできる行数の上限は5,000行となります。
また、図のように「Prefer」ヘッダーを指定することで、テーブルに格納されているレコードが5,000行を超えている場合にフラグを返させることができます。

⑤Dataverse Web APIでクエリ「fetchXml」を設定
「Microsoft Entra ID 付きの HTTP」コネクタの「HTTP 要求を呼び出す」アクションで、クエリ「fetchXml」を設定してDataverse Web APIを呼び出す方法です。 ④とは異なり、カウントできる行数の上限は50,000行となります。この50,000行の上限は、「システムの動作および信頼性を保持する」ためとして、Dataverse Web API側の仕様で、制限されているものです。

⑥Dataverseの「RetrieveTotalRecordCount」関数を実行
「Microsoft Entra ID 付きの HTTP」コネクタの「HTTP 要求を呼び出す」アクションで、Dataverseの「RetrieveTotalRecordCount」関数を呼び出す方法です。レコード件数を気にすることなくクラウドフローを最もシンプルに実装できるのはこの方法ですが、これで返される件数は、過去24時間以内のスナップショットから取得されたものなので、関数を呼び出したタイミングでの最新の値を取得できるとは限りません。
また、Power Platform環境の種類によって挙動が異なり、既定環境、実稼働環境、サンドボックス環境ではきちんとレコード数を取得できますが、試用環境や開発者環境では、レコード数が0件と返されるようです。このため、ALMを意識して、環境を跨いでソリューションパッケージを移行するような開発スタイルの場合には、種類の違いに気を付けておく必要があります。

さらに、「RetrieveTotalRecordCount」関数の呼び出しにおいて、クラウドフローにこだわらず、単に行数だけ確認できれば十分という場合には、対象のDataverseテーブルと同じPower Platform環境にある、任意のモデル駆動型アプリを起動して(Entra IDの認証が済んでおり、かつ、Power Platform環境の環境URLと同一のホスト名を持つURLを開いている状態)、以下のブックマークレットを実行するのが一番早いです。
javascript:function proc(){var r = JSON.parse(this.responseText).EntityRecordCountCollection,t = [];for (let i = 0; i < r.Keys.length; i++) {t.push(r.Keys[i]+"="+r.Values[i])}prompt("Result", t.join(","))} etn = prompt("Tables:", "ya_member").split(",").map((str) => str.replace(/\s/g,%27%27));var oReq = new XMLHttpRequest();oReq.addEventListener("load", proc);oReq.open("GET","api/data/v9.2/RetrieveTotalRecordCount(EntityNames=[%27"+etn.join("%27, %27")+"%27])");oReq.send(); |
ブラウザによって若干UIが異なりますが、例えばMicrosoft Edgeの場合、以下のように「お気に入りバー」にブックマークレットを登録しておくのがおすすめです。

Dataverseの「関数」
上で出てきたDataverseの「関数」とは、Dataverse Web APIで予め定義されている「データを取得するための操作」を指します。関数名(Name属性)を含む特定のエンドポイントに対して、HTTPリクエストを送信することによって、関数を利用することができます。
同じくDataverse Web APIで定義されているアクションとよく似ていますが、アクションではデータを変更することができ、関数ではできないという違いがあります。
また、「バインドされている(Bound)関数/アクション」と「バインドされていない(Unbound)関数/アクション」で、特定の単一テーブルを操作対象としているかどうかが異なります。今回利用した「RetrieveTotalRecordCount」関数の場合、EntityNamesパラメーターとして、テーブルの論理名を複数同時に指定するように定義されており、「特定の単一テーブル」のみを操作対象としているわけではないので、「バインドされていない(Unbound)関数」に分類される関数ということになります。
「強制同期」の可否
RetrieveTotalRecordCount関数で参照できる「過去24時間以内のスナップショット」のデータは、OperationTypeが「46(Regenerate Entity Row Count Snapshot Data)」となっている「システムジョブ」で更新されます。システムジョブの実体は、System Job (AsyncOperation) テーブルに格納されているレコードです。
そのため、このシステムジョブレコードを手動で作成することによって、スナップショットを強制的に更新できそうな気がしますが、実際にDataverse Web API宛てにPOSTリクエストを送信してレコードを作成しようとすると、エラーが出力され、レコードは作成されず、結果として強制的に更新することもできません。エラーコードは「405 Method Not Allowed」、エラーメッセージは「Direct enqueue of this system job is not allowed on operation type: '46'.」となっていることから、仕様として、手動更新させたくないということでしょうか…。
このように、①から⑥まで様々な実装方法があります。対象とするDataverseテーブルの規模や、Power Automateクラウドフローの実装難易度、カウントされるタイミングがそれぞれ異なるので、要件に応じて取捨選択する必要があります。
まとめ
今回は、Dataverseテーブルに格納されているレコードの件数を、Power Automateクラウドフローで取得する方法についてご紹介しました。
QES では Power Platform の開発支援、QAサポート、開発者教育、ガバナンス整備など、組織で Power Platform を活用するためのサポートを包括的にご提供しています。Power Platform 活用についてご興味がある/利用中だが課題を感じていらっしゃるお客様はまずはお気軽にお問い合わせください。
このブログで参照されている、Microsoft、Windows、その他のマイクロソフト製品およびサービスは、米国およびその他の国におけるマイクロソフトの商標または登録商標です。