Azure FunctionsからAzure SQL DatabaseやSQL Serverに接続している場合、STRING_SPLITの公式情報でまず確認すべき点は、互換性レベル130以上が原則であること、ただしAzure SQL Databaseではプレビューのデータベーススコープ構成ALLOW_BUILTIN_TVF_IN_ALL_COMPAT_LEVELSにより、互換性レベル要件の扱いが変わる可能性があることです。特に、関数アプリからCSV形式のID一覧、タグ、複数条件をSQLへ渡して処理している開発者は、設定・クエリ・デプロイ手順を一度見直しておくべきです。
STRING_SPLIT自体はAzure Functionsの機能ではなく、SQL Server系データベースで使うTransact-SQLのテーブル値関数です。しかし、Azure FunctionsのSQL入力バインド、SQLトリガー、独自のSqlClient接続からAzure SQL Databaseを呼び出している構成では、関数側の実装や本番展開に直接影響します。この記事では、2026年5月前後のMicrosoft公式情報をもとに、変更点、影響範囲、管理者・開発者が確認すべきポイントを実務目線で整理します。(Microsoft Learn)
Azure FunctionsでSTRING_SPLITを使う場面とは
STRING_SPLITは、区切り文字で連結された文字列を複数行に分割するTransact-SQL関数です。たとえば、'1,2,3'のような文字列をSQL側で行データに変換し、JOINやWHERE IN相当の条件に使えます。Microsoft Learnでは、STRING_SPLIT ( string , separator [ , enable_ordinal ] )という構文が案内されています。(Microsoft Learn)
Azure Functionsでは、次のような場面でSTRING_SPLITが使われやすいです。
- HTTPトリガーで受け取った複数IDをSQL検索条件にする
- キューやService Busから受け取ったCSV形式の値をSQLで分解する
- Azure SQL入力バインドのクエリで、複数のタグやカテゴリを絞り込む
- タイマー起動のバッチ関数で、設定値に含まれるリストをSQL側で展開する
- SQLトリガーで検知した変更データをもとに、関連レコードをまとめて処理する
Azure FunctionsのAzure SQLバインドは、Azure SQLおよびSQL Server製品に対して、入力バインド、出力バインド、SQLトリガーをサポートしています。つまり、Functionsのコードそのものではなく、接続先データベースで実行されるT-SQLの仕様変更や設定変更が、関数アプリの動作に影響する可能性があります。(Microsoft Learn)
今回確認すべき変更点
今回のポイントは、STRING_SPLITの基本構文が大きく変わったというより、互換性レベル要件に関する説明が更新され、ALLOW_BUILTIN_TVF_IN_ALL_COMPAT_LEVELSというデータベーススコープ構成への言及が追加されたことです。
Microsoft LearnのGitHub履歴では、2026年5月19日にAdd ALLOW_BUILTIN_TVF_IN_ALL_COMPAT_LEVELSというコミットがあり、STRING_SPLITのページにも「このデータベーススコープ構成が有効な場合、互換性レベル要件は適用されない」という説明が追加されています。(GitHub)
変更点の整理
| 確認項目 | 従来から重要だった内容 | 2026年5月前後の更新で特に見るべき内容 |
|---|---|---|
| 互換性レベル | STRING_SPLITは原則として互換性レベル130以上が必要 | ALLOW_BUILTIN_TVF_IN_ALL_COMPAT_LEVELSが有効な場合、互換性レベル要件が適用されない説明が追加 |
| 対象環境 | SQL Server 2016以降、Azure SQL Database、Azure SQL Managed Instanceなど | Azure SQL DatabaseとMicrosoft FabricのSQL databaseでプレビュー構成として扱われる点に注意 |
| 戻り値 | 通常はvalue列を返す | 第3引数enable_ordinalを1にするとordinal列も返せる |
| 並び順 | 分割後の行順は保証されない | 順序が必要な処理ではORDER BY ordinalを明示する必要がある |
| Azure Functionsへの影響 | 関数側から実行するSQLが失敗する可能性がある | 本番・検証・ローカルで互換性レベルやDBスコープ構成が違うと、動作差が出る |
ALLOW_BUILTIN_TVF_IN_ALL_COMPAT_LEVELSは、Azure SQL DatabaseとMicrosoft FabricのSQL databaseに適用されるプレビューのデータベーススコープ構成です。有効にすると、STRING_SPLITを含む一部の組み込みテーブル値関数を、互換性レベルに関係なく使用できると説明されています。(Microsoft Learn)
Azure Functions利用者への影響範囲
STRING_SPLITの更新は、Azure Functionsランタイムの変更ではありません。そのため、すべての関数アプリで即座にコード修正が必要になるわけではありません。
ただし、次の条件に当てはまる場合は、影響を受ける可能性があります。
| 対象 | 影響の可能性 | 確認すべきこと |
|---|---|---|
| Azure SQL Databaseへ接続する関数アプリ | 高 | 接続先DBの互換性レベル、DBスコープ構成、SQLクエリ |
| SQL Server 2016以降へ接続する関数アプリ | 中 | 互換性レベルが130以上か |
| SQL Server 2014以前、または互換性レベルが低いDB | 高 | STRING_SPLITが認識されない可能性 |
Azure SQL入力バインドでSTRING_SPLITを使うアプリ | 高 | バインド定義内のSQLとパラメーターの渡し方 |
| SQL出力バインドのみで単純INSERT/UPSERTするアプリ | 低 | 出力バインド自体より、ストアドプロシージャや後続処理のSQLを確認 |
独自コードでSqlConnectionやORMを使うアプリ | 中 | 生SQL、ストアドプロシージャ、動的SQLの有無 |
特に注意したいのは、開発環境と本番環境でデータベースの互換性レベルが異なるケースです。ローカルや検証用Azure SQLでは動くのに、本番DBではSTRING_SPLITが認識されない、または想定と異なる順序で処理される、といったトラブルが起こり得ます。
管理者が確認すべき設定
管理者は、まず接続先データベースの互換性レベルを確認します。STRING_SPLITは互換性レベル130以上が原則です。互換性レベルが130未満の場合、SQL ServerのデータベースエンジンはSTRING_SPLIT関数を見つけられないと公式ドキュメントで説明されています。(Microsoft Learn)
SELECT
name,
compatibility_level
FROM sys.databases
WHERE name = DB_NAME();
Azure SQL DatabaseでALLOW_BUILTIN_TVF_IN_ALL_COMPAT_LEVELSの利用を検討する場合は、プレビュー機能である点を踏まえて、本番環境では慎重に扱う必要があります。一般的には、まず互換性レベルを130以上にする方針を検討し、それが既存アプリに与える影響を評価したうえで判断するのが安全です。
SELECT
name,
value,
value_for_secondary
FROM sys.database_scoped_configurations
WHERE name = 'ALLOW_BUILTIN_TVF_IN_ALL_COMPAT_LEVELS';
設定変更を行う前には、次の観点で確認してください。
| 確認項目 | 理由 | 判断基準 |
|---|---|---|
| 互換性レベル | SQLの挙動やクエリ最適化に影響する可能性がある | 既存アプリの回帰テストができるか |
| 本番・検証DBの差異 | Functionsは環境ごとに接続先が変わりやすい | 同じSQLが全環境で通るか |
| DBスコープ構成 | プレビュー構成を使う場合、運用ルールが必要 | 本番利用の承認プロセスがあるか |
| Query Storeや監視 | 設定変更後の性能劣化を検知するため | 主要クエリの実行時間を比較できるか |
| ロールバック手順 | 変更後に予期せぬ影響が出る可能性がある | 変更前の設定値を記録しているか |
開発者が確認すべきクエリの書き方
STRING_SPLITをAzure Functionsから使う場合、問題になりやすいのは「動くかどうか」だけではありません。順序、空文字、データ型、SQLインジェクション対策まで確認する必要があります。
基本形はCROSS APPLYで展開する
テーブルの列にカンマ区切りのタグが入っている場合、CROSS APPLYで展開できます。
SELECT
p.ProductId,
p.Name,
s.value AS Tag
FROM dbo.Product AS p
CROSS APPLY STRING_SPLIT(p.Tags, ',') AS s;
ただし、分割後の順序は保証されません。公式ドキュメントでも、出力行の順序は入力文字列内の順序と一致する保証がなく、必要に応じてORDER BYを使う必要があると説明されています。(Microsoft Learn)
順序が必要ならenable_ordinalを使う
順序を使う処理では、第3引数に1を指定してordinal列を取得します。
SELECT
value,
ordinal
FROM STRING_SPLIT('first,second,third', ',', 1)
ORDER BY ordinal;
enable_ordinalは、Azure SQL Database、Azure SQL Managed Instance、Azure Synapse AnalyticsのサーバーレスSQLプール、SQL Server 2022以降で利用できます。第3引数を1にすると、value列に加えて、1始まりの位置を示すordinal列が返ります。(Microsoft Learn)
注意点は、enable_ordinalには列や変数ではなく、定数値を指定する必要があることです。実装時に@enableOrdinalのような変数を渡す設計にすると、エラーの原因になります。
空文字を除外する
連続した区切り文字がある場合、空文字の行が返ることがあります。
DECLARE @ids nvarchar(100) = N'101,102,,104';
SELECT value
FROM STRING_SPLIT(@ids, ',')
WHERE RTRIM(value) <> '';
HTTPリクエストや外部システムから渡された値では、1,2,,4のような入力が珍しくありません。空文字をそのままJOINやCASTに使うと、変換エラーや不要な検索条件につながります。
数値IDはTRY_CONVERTで安全に扱う
Azure FunctionsのHTTPトリガーでids=1,2,3のような値を受け取り、SQLに渡すケースでは、文字列をそのまま結合条件に使わない方が安全です。
DECLARE @ids nvarchar(max) = @InputIds;
WITH ParsedIds AS (
SELECT TRY_CONVERT(int, value) AS Id
FROM STRING_SPLIT(@ids, ',')
WHERE RTRIM(value) <> ''
)
SELECT t.*
FROM dbo.TargetTable AS t
JOIN ParsedIds AS p
ON p.Id = t.Id
WHERE p.Id IS NOT NULL;
TRY_CONVERTを使うと、数値に変換できない値をNULLとして扱えます。これにより、abcのような不正値が混ざっても、いきなり関数全体が失敗するリスクを下げられます。
Azure Functionsでの実装時に避けたい失敗
CSVをそのままSQL文字列に連結しない
Azure Functionsで受け取ったパラメーターを、次のようにSQL文字列へ直接連結するのは避けるべきです。
// 避けたい例
var sql = $"SELECT * FROM dbo.Items WHERE Id IN ({ids})";
この方法は、SQLインジェクションや予期しない構文エラーの原因になります。複数値を渡したい場合は、パラメーターとしてCSV文字列を渡し、SQL側でSTRING_SPLITとTRY_CONVERTを使って処理する方が安全です。
Azure SQL入力バインドではクエリの責務を明確にする
Azure FunctionsのAzure SQL入力バインドは、関数実行時にデータベースからデータを取得して入力パラメーターへ渡す仕組みです。複雑なリスト処理を入力バインドのSQLに直接書く場合は、可読性とテスト容易性が下がりやすくなります。(Microsoft Learn)
単純な検索なら入力バインドで問題ありません。一方で、STRING_SPLIT、複数JOIN、権限制御、入力値検証が絡む場合は、ストアドプロシージャやアプリケーションコード側で責務を整理した方が保守しやすい場合があります。
判断の目安は次の通りです。
| 実装方針 | 向いているケース | 注意点 |
|---|---|---|
| SQL入力バインドに直接記述 | 条件が単純で、少数のパラメーターだけ使う | SQLが長くなるとレビューしづらい |
| ストアドプロシージャ化 | 複数値の検証、JOIN、権限制御がある | DB変更のデプロイ手順が必要 |
| アプリコードで分割して個別パラメーター化 | 件数が少なく、SQL側で分割する必要がない | パラメーター数が増えすぎると管理しづらい |
| テーブル値パラメーターを使う | .NETなどで大量IDを安全に渡したい | バインドや言語によって実装しやすさが異なる |
移行・展開時のチェックリスト
本番環境でAzure FunctionsとAzure SQLを連携している場合、STRING_SPLIT関連の見直しは、単なるSQL修正ではなく展開手順の一部として扱うべきです。
| フェーズ | 確認内容 | 具体的な作業 |
|---|---|---|
| 調査 | STRING_SPLIT利用箇所 | SQLファイル、ストアドプロシージャ、Functionコード、バインド定義を検索 |
| 環境確認 | 互換性レベル | 本番・検証・開発DBでsys.databasesを確認 |
| 設定確認 | DBスコープ構成 | sys.database_scoped_configurationsを確認 |
| 実装確認 | 順序依存 | ORDER BY ordinalが必要な処理を洗い出す |
| 入力確認 | 空文字・不正値 | WHERE value <> ''やTRY_CONVERTを追加 |
| セキュリティ | SQL文字列連結 | パラメーター化されているか確認 |
| 展開 | Functions設定 | 接続文字列、スロット設定、環境変数を確認 |
| 監視 | 性能・失敗率 | デプロイ前後で実行時間、SQLエラー、タイムアウトを比較 |
Azure FunctionsのAzure SQLバインドでは、接続文字列がMicrosoft.Data.SqlClientへ渡され、Command timeoutやConnectRetryCount、Poolingなどの接続関連キーワードも重要です。クエリが複雑化してタイムアウトしやすい場合は、SQLの見直しとあわせて接続設定も確認してください。(Microsoft Learn)
セキュリティ面ではマネージドIDも合わせて確認する
STRING_SPLITの見直しと同時に、Azure FunctionsからAzure SQL Databaseへの接続方式も確認しておくと効率的です。Microsoftは、FunctionsとAzure SQL Databaseの接続に、ユーザー名・パスワードではなくMicrosoft Entra IDとマネージドIDを使うことを推奨しています。(Microsoft Learn)
マネージドIDを使う場合は、次の手順を確認します。
| 手順 | 内容 |
|---|---|
| Microsoft Entra認証を有効化 | Azure SQLサーバーにMicrosoft Entra管理者を設定 |
| Function AppのマネージドIDを有効化 | システム割り当て、またはユーザー割り当てIDを使う |
| DBユーザーを作成 | CREATE USER [identity-name] FROM EXTERNAL PROVIDER;を実行 |
| 権限を付与 | 必要最小限のロール、または個別権限を付与 |
| 接続文字列を更新 | 認証方式をマネージドID向けに変更 |
| 本番スロットで確認 | スロットごとのアプリ設定差異を確認 |
STRING_SPLITを使うSQLは、検索条件やIDリストを扱うことが多いため、権限が広すぎる接続ユーザーで実行されているとリスクが大きくなります。読み取りだけの関数には読み取り権限、更新が必要な関数には対象テーブルに限定した権限を付けるなど、最小権限を意識してください。
順序に依存する処理は必ずテストする
STRING_SPLITで最も見落とされやすいのは、分割後の順序です。たとえば、Azure Functionsで次のような入力を受け取ったとします。
statusFlow=received,validated,processed,completed
この値をSQL側で分割し、ワークフロー順に処理したい場合、STRING_SPLIT(statusFlow, ',')だけでは不十分です。順序が保証されないため、たまたま正しく見えても、本番環境や別の実行計画で順序が変わる可能性があります。
順序が必要なら、次のようにenable_ordinalとORDER BY ordinalを使います。
SELECT
value AS StatusName,
ordinal AS StepNo
FROM STRING_SPLIT(@statusFlow, ',', 1)
ORDER BY ordinal;
ただし、第3引数が利用できる環境かどうかも確認してください。古いSQL Serverや互換性の低い環境では、構文自体が使えない場合があります。
Azure Functionsのデプロイで注意すべきポイント
Azure Functionsでは、アプリ設定や接続先を環境ごとに切り替えることが多いため、SQLの仕様差が見えにくくなります。特にデプロイスロットを使っている場合、ステージングでは動作するのに、本番スワップ後に失敗することがあります。
確認すべきポイントは次の通りです。
- ステージングと本番で同じAzure SQL Databaseを見ているか
- 接続文字列のスロット設定が意図通りか
- 本番DBの互換性レベルが検証DBと同じか
- SQL拡張機能パッケージやExtension Bundleのバージョンが揃っているか
- SQLトリガー、入力バインド、独自SQL実行のどこで
STRING_SPLITを使っているか
Azure FunctionsのAzure SQLバインドでは、C#の分離ワーカーモデルとインプロセスモデルで利用するNuGetパッケージが異なります。また、インプロセスモデルは2026年11月10日にサポート終了予定と案内されているため、C#関数ではSQLまわりの見直しとあわせて分離ワーカーモデルへの移行計画も確認しておくべきです。(Microsoft Learn)
すぐ確認すべき実務ポイント
今回の公式情報を受けて、管理者と開発者がすぐに行うべきことは次の3つです。
まず、接続先データベースの互換性レベルを確認してください。STRING_SPLITが使えるはずなのにエラーになる場合、SQLの書き方ではなく、互換性レベルが原因のことがあります。
次に、STRING_SPLITの利用箇所で順序依存がないか確認します。順序が必要な処理では、enable_ordinalとORDER BY ordinalを使える環境かどうかまで確認してください。
最後に、Azure Functionsの接続方式とデプロイ設定を確認します。マネージドID、接続文字列、SQLバインド拡張機能、ステージングと本番のDB差異を見直すことで、SQL更新に伴う本番障害を防ぎやすくなります。
STRING_SPLITは便利な関数ですが、Azure Functionsから使う場合は「SQL側の小さな関数」ではなく、「入力値、接続設定、DB互換性、展開手順がつながる実装ポイント」として扱うことが重要です。まずは利用箇所を検索し、互換性レベル、順序、空文字、不正値、接続権限の順に確認していきましょう。

コメント