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"},            
   ]  
}