Power AutomateのSQL Serverコネクタ「Get rows (V2)」で日時フィルターが使えない/エラーの原因と5つの解決策【OData・UTC・ゲートウェイ完全版】

Power Automate の SQL Server コネクタ「Get rows (V2)」に OData 形式の日時フィルターを指定するとエラーになる——この現象はクラウド(Azure SQL)/オンプレミス(ゲートウェイ)双方で起こり得ます。本記事では原因を分解し、ストアドプロシージャを新設せずに実装できる現実的な代替策と、長期運用を見据えた設計・チューニングのベストプラクティスまでを丁寧に解説します。

目次

問題の概要(再現と現象)

Power Automate の SQL Server コネクタ → Get rows (V2) アクションで、Filter Query に OData 形式の日時条件を設定すると、次のような入力で失敗することがあります。

column1 gt 2025-09-05T00:00:00Z and column2 lt 2025-09-06T00:00:00Z

よく見られる症状の例:

  • 「型 ‘Edm.DateTimeOffset’ と ‘Edm.String’ の比較演算子が定義されていない」旨のエラー
  • 「日付の解析に失敗」や「演算子が無効」などの OData 由来のメッセージ
  • オンプレミス データ ゲートウェイ経由だと Z(Zulu/UTC) 指定や小数秒の扱いで失敗しやすい

同じ条件でも、Azure SQL 直結とオンプレミス(ゲートウェイ経由)で挙動が異なることがあり、環境差がトラブルの温床になりがちです。

なぜ日時フィルターが通らないのか(内部のギャップ)

Get rows (V2) の Filter Query は OData の構文に「近い」ものの、実装は各コネクタ/ドライバで部分的に異なります。特に以下のギャップが原因になりやすいポイントです。

  • 書式の解釈差:YYYY-MM-DDThh:mm:ssZ(UTC)や +09:00 のオフセット付き、ミリ秒/小数秒の有無などで解釈が分かれる。
  • 型マッピングの非対称:SQL の datetime/datetime2/datetimeoffset と、OData の Edm.DateTimeOffset/Edm.Date の相互変換でズレが生じる。
  • ゲートウェイ経由の変換:オンプレミスではドライバ層の日時解析・ロケール設定の影響を受けやすい。
  • 最適化の制約:OData 側で関数(year() 等)を使うと SQL に非 SARGable(インデックス非活用)な式が投下され、性能悪化やタイムアウトを招く。

列型 × リテラル × 結果の傾向(簡易マトリクス)

SQL列型ODataリテラル例典型的な結果リスク/備考
datetime2025-09-05T00:00:00Z失敗しがち古い型でタイムゾーン情報なし。Z 指定で不一致や桁あふれが起きることがある。
datetime22025-09-05T00:00:00環境により可/不可小数秒桁の差異・オフセット有無でばらつき。クォート有無の差で挙動が変わる報告あり。
datetimeoffset2025-09-05T00:00:00+09:00比較的安定OData と親和性が高いが、ゲートウェイ側の解析実装に依存する場合がある。
date'2025-09-05' または 2025-09-05安定しやすい「日付だけ」の比較は OData 的にも扱いやすく、障害回避として有効。

解決策の比較(早見表)

解決策内容メリットデメリット/注意点推奨度
① Execute a SQL query (V2)パラメータ化クエリで直接 T-SQL を実行。
SELECT * FROM dbo.MyTable WHERE column1 >= @startDate AND column1 < @endDate
UTC/オフセットを正確に扱える。
インデックス活用(SARGable)。
SQLインジェクション耐性。
オンプレミスはゲートウェイ設定が必要。
ガバナンスにより生SQL禁止の場合は不可。
高(第一候補)
② 計算列(永続化)+インデックスALTER TABLE ... ADD DateOnly AS CONVERT(date, column1) PERSISTED;OData の日付比較で安定。
既存インデックスと両立。
スキーマ変更が必要。
列追加の審査・リリース手続きが発生。
高(長期運用向け)
③ ビューで日付専用列を公開CREATE VIEW ... AS SELECT CONVERT(date, column1) AS DateOnly ...本番テーブルを直接変更しない。非 SARGable になる可能性。
維持管理コスト。
中(制約下の代替)
④ 取得後に Flow 側で Filter arrayまず全件(もしくは Top)取得後にフローでフィルタリング。実装最短。コネクタ差異の影響を受けにくい。件数が多いと遅い・コスト増。
スロットリングのリスク。
低〜中(小規模のみ)
⑤ year()/month()/day() を使う暫定策year(column1) eq 2025 and month(column1) eq 9 ...OData だけで完結。非 SARGable で遅い。
境界条件の漏れやすさ。
低(緊急回避のみ)

解決策①:Execute a SQL query (V2) でパラメータ化する

基本のパターン(UTC で半開区間)

-- 期間開始(含む)〜期間終了(含まない)の半開区間が原則
SELECT *
FROM dbo.MyTable
WHERE column1 &gt;= @startDate  -- 例: 2025-09-05T00:00:00Z
  AND column1 &lt;  @endDate;   -- 例: 2025-09-06T00:00:00Z

半開区間(終了を「含まない」)にすることで、ミリ秒・小数秒の丸め誤差や「23:59:59.999 の取りこぼし」を確実に避けられます。Power Automate 側では次のような式でパラメータ値を作れます。

  • @{formatDateTime(utcNow(),'yyyy-MM-ddT00:00:00Z')}
  • @{formatDateTime(addDays(utcNow(),1),'yyyy-MM-ddT00:00:00Z')}

列型が datetime2 の場合

@startDate/@endDate を datetime2 として解釈させるため、ISO 8601 形式(Z 付きでも可)を渡します。必要に応じて SQL 側で明示キャストして安全側に倒します。

SELECT *
FROM dbo.MyTable
WHERE column1 &gt;= CAST(@startDate AS datetime2(7))
  AND column1 &lt;  CAST(@endDate   AS datetime2(7));

列型が datetimeoffset の場合(タイムゾーンを使う)

SELECT *
FROM dbo.MyTable
WHERE column1 &gt;= CAST(@startDate AS datetimeoffset)
  AND column1 &lt;  CAST(@endDate   AS datetimeoffset);

ローカル時刻で日付指定したい場合は、アプリ側(Flow)で convertTimeZone() を用いて UTC に変換してから渡すと一貫性が保てます。

ベストプラクティス(SQL クエリ)

  • 必ずインデックス列に対し「列 >= パラメータ AND 列 < パラメータ」の形にする(左右を関数でラップしない)。
  • 必要に応じて ORDER BY column1 を付与し、ページング利用時の順序不安定を防ぐ。
  • 大量データではキーセットページング:
    WHERE (column1 >= @startDate AND column1 < @endDate) AND id > @lastId ORDER BY id
  • 権限は SELECT 最小限にし、書込権限を与えない。

Power Automate の実装手順(要点)

  1. 「SQL Server」コネクタの「Execute a SQL query (V2)」を追加。
  2. クエリに @startDate・@endDate を記述。
  3. 「パラメータ」に動的コンテンツ(上記の formatDateTime())を割当。
  4. オンプレミスの場合、ゲートウェイを最新に更新し、接続文字列の暗号化やタイムゾーン設定を確認。

解決策②:計算列(永続化)+インデックスで OData を「日付だけ」にする

Get rows (V2) の日時比較が不安定でも、「日付のみ」の比較は安定しやすいです。そこで、日付を永続化した計算列を作り、インデックスを張って OData 側で日付範囲を指定します。

ALTER TABLE dbo.MyTable
  ADD DateOnly AS CONVERT(date, column1) PERSISTED;

CREATE INDEX IX_MyTable_DateOnly ON dbo.MyTable(DateOnly); 

以降、Filter Query の例:

DateOnly ge 2025-09-05 and DateOnly lt 2025-09-06

環境によってはクォートの有無('2025-09-05' vs 2025-09-05)で挙動が変わることがあります。安定しない場合は双方を試し、統一ルールをチーム内で明文化するとよいでしょう。

UTC とローカル時刻の整合

保存値が UTC の datetime2 で、ローカル日付で検索したい場合は、計算列でタイムゾーン変換を固定してから date 化することもできます。

-- 例:JST 基準の DateOnlyJst を永続化
ALTER TABLE dbo.MyTable
  ADD DateOnlyJst AS CONVERT(date, (column1 AT TIME ZONE 'UTC') AT TIME ZONE 'Tokyo Standard Time') PERSISTED;

CREATE INDEX IX_MyTable_DateOnlyJst ON dbo.MyTable(DateOnlyJst); 

ローカル基準日付で OData フィルターを安定させたい要件に有効です。

解決策③:ビューで日付専用列を公開(本体を触れない場合)

本番テーブルに手を入れたくない場合は、ビューで date 列を公開して回避できます。

CREATE VIEW dbo.v_MyTable
AS
SELECT
  key,
  column1,
  CONVERT(date, column1) AS DateOnly
FROM dbo.MyTable;

ただしビューの DateOnly は永続化されないため、検索式は非 SARGable になりがちです。性能要求が厳しい場合は解決策②(永続化)や①(パラメータ化)を選ぶのが安全です。

解決策④:いったん取得して Flow 側で絞る(小規模・短期向け)

件数が僅少なら、まず Get rows (V2) で取得し、Filter array アクションで日時条件を適用する方法があります。

@and(
  greaterOrEquals(item()?['column1'],'2025-09-05T00:00:00Z'),
  less(item()?['column1'],'2025-09-06T00:00:00Z')
)

ただし大量データでは遅延・スロットリング・ランコスト増のリスクが高く、恒常運用には不向きです。暫定策として割り切り、早期に①か②へ移行しましょう。

解決策⑤:OData の year()/month()/day() を使う暫定策

Filter Query に次のような式を使えば、OData 側だけで日付を構成できます。

year(column1) eq 2025 and month(column1) eq 9 and day(column1) eq 5

ただしこの方法は SQL に「CONVERT/DATEPART 相当の関数を列側に適用」する形で送られ、非 SARGable になりやすく、インデックスが効かずに遅くなります。緊急回避以外では推奨しません。

よくある落とし穴と対処

  • 境界条件の取りこぼし:
    終了時刻を「含む」にすると 23:59:59.997〜.999 の微小差で漏れがち。半開区間(<)に統一する。
  • Z(UTC)とオフセット:
    ゲートウェイ経由では Z の解釈で失敗するケースがある。+00:00 を明示するか、Flow 側で UTC 化して素の yyyy-MM-ddTHH:mm:ss を渡す。
  • 小数秒桁数:
    datetime2(7) 列に .0 しか渡さない/逆に .1234567 を渡すなど、桁差で比較が不整合になることがある。必要なら SQL 側で CAST(... AS datetime2(3)) に丸める。
  • 型の不一致:
    列が datetime なのに datetimeoffset リテラルを渡す等で失敗。列の基準(UTC かローカルか)をチームで固定する。
  • クォートの有無:
    OData の実装差で、'2025-09-05' と 2025-09-05 のどちらかしか通らない環境がある。どちらが正と決め、テンプレ化する。

設計のベストプラクティス(長期運用・性能)

  • 保存は UTC、表示でローカル化:
    保存は datetime2(推奨)または datetimeoffset で UTC を原則に。表示やレポートで AT TIME ZONE を用いてローカル化。
  • インデックス整備:
    フィルターに使う列に単独(または先頭)キーのインデックスを作成。計算列方式なら計算列自体にインデックス。
  • ページング戦略:
    大量データはキーセットページング(WHERE id > @lastId)で再実行耐性と性能を確保。
  • 監査・追跡:
    フローから「実行 ID」等をパラメータで渡し、テーブルに書き出しておくと後追い調査が容易。

ケース別の実装レシピ

クラウド(Azure SQL)で UTC の 1 日分を取得

-- 2025-09-05 の 1 日分(UTC)
SELECT *
FROM dbo.MyTable
WHERE column1 &gt;= @d0  -- 2025-09-05T00:00:00Z
  AND column1 &lt;  @d1; -- 2025-09-06T00:00:00Z

オンプレミス(ゲートウェイ)で JST 基準の 1 日分を取得(列は UTC)

-- 列: datetime2(3) UTC 保存
-- パラメータ: JST の 0:00 と翌日 0:00 を Flow で作り、SQL で UTC に変換
SELECT *
FROM dbo.MyTable
WHERE column1 &gt;= (CAST(@jstStart AS datetimeoffset) AT TIME ZONE 'UTC')
  AND column1 &lt;  (CAST(@jstEnd   AS datetimeoffset) AT TIME ZONE 'UTC');

OData で日付だけフィルターする(計算列利用)

DateOnly ge 2025-09-05 and DateOnly lt 2025-09-06

Power Automate:式サンプル集(コピペ可)

用途式メモ
今日 0:00 UTC@{formatDateTime(utcNow(),'yyyy-MM-ddT00:00:00Z')}開始境界に。
明日 0:00 UTC@{formatDateTime(addDays(utcNow(),1),'yyyy-MM-ddT00:00:00Z')}終了境界に(半開区間)。
任意タイムゾーン開始(JST 例)@{formatDateTime(convertTimeZone(utcNow(),'UTC','Tokyo Standard Time'),'yyyy-MM-ddT00:00:00')}必要なら Z 付与か SQL で UTC 化。
Filter array(ISO 8601 比較)@and(greaterOrEquals(item()?['column1'],variables('startUtc')),less(item()?['column1'],variables('endUtc')))小数秒を含む場合はフォーマット統一。

トラブルシューティング・チェックリスト

  • 列のデータ型は? datetime なら datetime2 への移行を検討。
  • 保存の基準は UTC ? ローカル? チーム内ルールが明文化されているか。
  • OData のリテラルはクォート要/不要? プロジェクト内で統一されているか。
  • 小数秒の桁合わせはできているか(datetime2(3) で固定するなど)。
  • インデックスは有効に使われているか(実行計画でスキャンになっていないか)。
  • オンプレはゲートウェイのバージョン・接続方式(暗号化/経路)を最新・適正に保てているか。

FAQ

Q. Get rows (V2) の日時フィルターが通らないのは仕様ですか?
A. 仕様というより、OData 側の書式と SQL 側の型・変換の「ギャップ」で失敗しやすい箇所がある、というのが実態です。安定を重視するなら①(パラメータ化)か②(計算列)を選びましょう。

Q. Z(UTC)を付けると失敗します。
A. 環境により Z の解析で失敗することがあります。+00:00 を使う/Z を外す/Flow 側で UTC 文字列を作り SQL で型化する、などで回避できます。

Q. 文字列のまま比較しても良いですか?
A. 文字列比較は桁/書式の揺れで誤判定の元です。SQL 側で datetime2/datetimeoffset にキャストし、列側に関数をかけない条件式にしましょう。

Q. year()/month()/day() で十分では?
A. 簡便ですが非 SARGable で遅く、規模が大きくなると破綻します。緊急時以外は避けてください。

Q. ストアドプロシージャは本当に不要?
A. 多くのケースで不要です。①のパラメータ化クエリで十分実現できます。組織ポリシーで生 SQL 禁止なら、ビューや SP の採用を検討してください。

Q. OData の日付はシングルクォートが必要?
A. 実装差があります。クォート有/無のどちらが通るかを確認し、プロジェクト標準を固定してください。

まとめ:最短で成果を出す選び方

前提/制約推奨アプローチ理由
クラウド接続可/生 SQL 可① パラメータ化クエリ最小変更・高性能・高安定。UTC/オフセットの整合を確保しやすい。
DB スキーマ変更可/性能重視② 計算列(永続化)+インデックスOData の日付比較で安定。Get rows (V2) を継続利用可能。
本体を触れない/運用許容③ ビューで日付公開暫定回避。性能要件次第で②へ移行。
小規模・短期間④ 取得後に Filter array実装最短。件数増に弱い点だけ注意。
緊急のつなぎ⑤ year()/month()/day()一時対応のみ。長期運用は非推奨。

サンプル一式(コピペして試せる)

テーブルとデータ

CREATE TABLE dbo.MyTable
(
  id        bigint IDENTITY(1,1) PRIMARY KEY,
  column1   datetime2(3) NOT NULL,   -- 例:イベント開始UTC
  column2   datetime2(3) NULL,       -- 例:イベント終了UTC
  payload   nvarchar(200) NULL
);

INSERT INTO dbo.MyTable(column1, column2, payload) VALUES
('2025-09-04T23:59:59.900', '2025-09-05T01:00:00.000', N'pre'),
('2025-09-05T00:00:00.000', '2025-09-05T02:00:00.000', N'start'),
('2025-09-05T23:59:59.999', '2025-09-06T00:30:00.000', N'end'),
('2025-09-06T00:00:00.000', NULL,                          N'next'); 

① パラメータ化クエリ例(半開区間)

SELECT id, column1, column2, payload
FROM dbo.MyTable
WHERE column1 &gt;= @startDate  -- 2025-09-05T00:00:00Z
  AND column1 &lt;  @endDate;   -- 2025-09-06T00:00:00Z

② 計算列+インデックス

ALTER TABLE dbo.MyTable
  ADD DateOnly AS CONVERT(date, column1) PERSISTED;

CREATE INDEX IX_MyTable_DateOnly ON dbo.MyTable(DateOnly); 

Filter Query:

DateOnly ge 2025-09-05 and DateOnly lt 2025-09-06

③ ビューで日付公開

CREATE VIEW dbo.v_MyTable
AS
SELECT id, column1, column2, payload, CONVERT(date, column1) AS DateOnly
FROM dbo.MyTable;

運用ノート(品質と保守性)

  • テストデータで境界検証:00:00:00.000 と 23:59:59.999、小数秒あり/なしのパターンを最低限カバー。
  • ロケール・タイムゾーンの固定:Power Automate の環境設定/式で明示的に UTC を扱い、SQL 側で必要に応じてローカル化。
  • コードの再利用:クエリ断片・式をソリューション内のテンプレートとして共有し、二重管理を避ける。
  • 監視:実行時間・取得件数・再試行回数をカスタム ログに集計し、しきい値超過で通知。

結論

「Get rows (V2) に OData の日時条件が通らない」問題は、OData と SQL の型・書式のすれ違いが主因です。最優先は① Execute a SQL query (V2) によるパラメータ化。これが組織制約で難しい場合は、② 計算列(永続化)+インデックスで OData を「日付だけ」に寄せて安定化するのが現実解です。短期の暫定や小規模には④、緊急回避には⑤を用いつつ、将来的には①または②に一本化する方針が、品質・性能・保守性の観点で最も費用対効果に優れます。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次