В реляционных базах данных параметризованный запрос — это запрос, в котором для параметров используются заполнители, а значения параметров предоставляются во время выполнения. 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, где в этом SqlParameterCollection определен параметр Id, назначенный свойству параметра этого 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
Давайте посмотрим на другой пример. Мы можем написать запрос, который принимает в качестве параметров фамилию и адресное состояние, а затем выполняет его для различных значений lastname и location.state на основе пользовательского ввода.
SELECT * FROM Families f WHERE f.lastName = @lastName AND f.location.state = @addressState
Этот запрос затем можно отправить в DocumentDB в виде параметризованного запроса JSON, как показано в следующем коде.