DocumentDB SQL - Parametrizado

Em bancos de dados relacionais, uma consulta parametrizada é uma consulta na qual marcadores de posição são usados ​​para parâmetros e os valores dos parâmetros são fornecidos em tempo de execução. DocumentDB também oferece suporte a consultas parametrizadas, e os parâmetros em consultas parametrizadas podem ser expressos com a conhecida notação @. O motivo mais importante para usar consultas parametrizadas é evitar ataques de injeção de SQL. Ele também pode fornecer manipulação robusta e escape de entrada do usuário.

Vamos dar uma olhada em um exemplo em que usaremos o .Net SDK. A seguir está o código que excluirá a coleção.

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); 
}

A construção de uma consulta parametrizada é a seguinte.

var query = new SqlQuerySpec { 
   QueryText = "SELECT * FROM c WHERE c.id = @id",
   Parameters = new SqlParameterCollection { new SqlParameter { Name = 
      "@id", Value = collectionId } } 
};

Não estamos codificando o collectionId, portanto, este método pode ser usado para excluir qualquer coleção. Podemos usar o símbolo '@' para prefixar nomes de parâmetro, semelhante ao SQL Server.

No exemplo acima, estamos consultando por uma coleção específica por Id onde o parâmetro Id é definido neste SqlParameterCollection atribuído à propriedade do parâmetro deste SqlQuerySpec. O SDK então faz o trabalho de construir a string de consulta final para DocumentDB com o collectionId embutido dentro dele. Executamos a consulta e, em seguida, usamos seu SelfLink para excluir a coleção.

A seguir está a implementação da tarefa 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"); 
   } 
}

Quando o código é executado, ele produz a seguinte saída.

**** Delete Collection MyCollection1 in mydb **** 
Deleted collection MyCollection1 from database myfirstdb 
 
**** Delete Collection MyCollection2 in mydb **** 
Deleted collection MyCollection2 from database myfirstdb

Vamos dar uma olhada em outro exemplo. Podemos escrever uma consulta que recebe o sobrenome e o estado do endereço como parâmetros e, em seguida, a executa para vários valores de sobrenome e local.estado com base na entrada do usuário.

SELECT *  
FROM Families f 
WHERE f.lastName = @lastName AND f.location.state = @addressState

Essa solicitação pode ser enviada ao Banco de Dados de Documentos como uma consulta JSON parametrizada, conforme mostrado no código a seguir.

{       
   "query": "SELECT * FROM Families f WHERE f.lastName = @lastName AND 
      f.location.state = @addressState", 
		
   "parameters": [           
      {"name": "@lastName", "value": "Wakefield"},          
      {"name": "@addressState", "value": "NY"},            
   ]  
}