DocumentDB SQL - 参数化

在关系数据库中,参数化查询是一种使用占位符作为参数并在执行时提供参数值的查询。 DocumentDB还支持参数化查询,参数化查询中的参数可以用熟悉的@表示法表示。 使用参数化查询的最重要原因是避免 SQL 注入攻击。 它还可以提供强大的用户输入处理和转义功能。

让我们看一个将使用 .Net SDK 的示例。 以下是删除集合的代码。

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 参数在此 SqlParameterCollection 中定义,并分配给此 SqlQuerySpec 的参数属性。 然后,SDK 会为 DocumentDB 构建最终查询字符串,并将 collectionId 嵌入其中。 我们运行查询,然后使用其 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"},            
   ]  
}