DocumentDBSQL-パラメータ化
リレーショナルデータベースでは、パラメーター化されたクエリは、プレースホルダーがパラメーターに使用され、パラメーター値が実行時に提供されるクエリです。DocumentDBはパラメーター化されたクエリもサポートしており、パラメーター化されたクエリのパラメーターは、使い慣れた@表記で表すことができます。パラメータ化されたクエリを使用する最も重要な理由は、SQLインジェクション攻撃を回避することです。また、ユーザー入力の堅牢な処理とエスケープを提供できます。
.NetSDKを使用する例を見てみましょう。以下は、コレクションを削除するコードです。
private async static Task DeleteCollection(DocumentClient client, string collectionId) {
Console.WriteLine();
Console.WriteLine(">>> Delete Collection {0} in {1} <<<",
collectionId, _database.Id);
var query = new SqlQuerySpec {
QueryText = "SELECT * FROM c WHERE c.id = @id",
Parameters = new SqlParameterCollection { new SqlParameter { Name =
"@id", Value = collectionId } }
};
DocumentCollection collection = client.CreateDocumentCollectionQuery(database.SelfLink,
query).AsEnumerable().First();
await client.DeleteDocumentCollectionAsync(collection.SelfLink);
Console.WriteLine("Deleted collection {0} from database {1}",
collectionId, _database.Id);
}
パラメータ化されたクエリの構成は次のとおりです。
var query = new SqlQuerySpec {
QueryText = "SELECT * FROM c WHERE c.id = @id",
Parameters = new SqlParameterCollection { new SqlParameter { Name =
"@id", Value = collectionId } }
};
collectionIdをハードコーディングしていないため、このメソッドを使用して任意のコレクションを削除できます。SQL Serverと同様に、「@」記号を使用してパラメーター名のプレフィックスを付けることができます。
上記の例では、Idによって特定のコレクションをクエリしています。Idパラメータは、このSqlQuerySpecのパラメータのプロパティに割り当てられたこのSqlParameterCollectionで定義されています。次に、SDKは、collectionIdが埋め込まれたDocumentDBの最終的なクエリ文字列を作成する作業を行います。クエリを実行し、そのSelfLinkを使用してコレクションを削除します。
以下は、CreateDocumentClientタスクの実装です。
private static async Task CreateDocumentClient() {
// Create a new instance of the DocumentClient
using (var client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey)) {
database = client.CreateDatabaseQuery("SELECT * FROM
c WHERE c.id = 'earthquake'").AsEnumerable().First();
collection = client.CreateDocumentCollectionQuery(database.CollectionsLink,
"SELECT * FROM c WHERE c.id = 'myfirstdb'").AsEnumerable().First();
await DeleteCollection(client, "MyCollection1");
await DeleteCollection(client, "MyCollection2");
}
}
コードを実行すると、次の出力が生成されます。
**** Delete Collection MyCollection1 in mydb ****
Deleted collection MyCollection1 from database myfirstdb
**** Delete Collection MyCollection2 in mydb ****
Deleted collection MyCollection2 from database myfirstdb
別の例を見てみましょう。姓と住所の状態をパラメーターとして受け取り、ユーザー入力に基づいて姓とlocation.stateのさまざまな値に対して実行するクエリを作成できます。
SELECT *
FROM Families f
WHERE f.lastName = @lastName AND f.location.state = @addressState
このリクエストは、次のコードに示すように、パラメーター化されたJSONクエリとしてDocumentDBに送信できます。
{
"query": "SELECT * FROM Families f WHERE f.lastName = @lastName AND
f.location.state = @addressState",
"parameters": [
{"name": "@lastName", "value": "Wakefield"},
{"name": "@addressState", "value": "NY"},
]
}