Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Троелсен Э. Язык программирования С# 2010 и п...docx
Скачиваний:
113
Добавлен:
21.09.2019
Размер:
6.92 Mб
Скачать

Работа с объектами параметризованных команд

Показанная выше программная логика вставки, обновления и удаления работает так, как и ожидается, однако обратите внимание на то, что каждый из SQL-запросов здесь представлен "жестко" закодированными строковыми литералами. Вы, возможно, знаете, что с SQL-параметрами можно обращаться, как с объектами, а не с простыми строками текста, если использовать параметризованные запросыОбычно параметризованные запросы выполняются намного быстрее буквальных SQL-строк, поскольку они анализируются только один раз (а не каждый раз, когда SQL-строка присваивается свойству CommandText). Параметризованные запросы также обеспечивают защиту от атак SQL-инъекции (это известная проблема безопасности доступа к данным).

Объекты команд ADO.NET поддерживают коллекцию дискретных типов параметра. По умолчанию эта коллекция пуста, но вы можете добавить в нее любое число объектов параметра, которые должны будут отображаться в "заместитель" параметра в SQL-запросе. Чтобы ассоциировать параметр в SQL-запросе с членом коллекции параметров данного объекта команды, добавьте к текстовому SQL-параметру префикс @ (это работает, как минимум, при использовании Microsoft SQL Server, но такое обозначение поддерживают не все СУБД).

Указание параметров с помощью типа DbParameter

Перед тем как приступить к построению параметризованных запросов, мы должны рассмотреть тип DbParameter (который является базовым классом объектов параметров, специфичных для конкретного поставщика данных). Этот класс поддерживает ряд свойств, позволяющих указать имя, размер и тип данных параметра, а также другие его особенности, например направление параметра. В табл. 22.8 описаны некоторые свойства типа DbParameter.

Таблица 22.8. Ключевые члены типа DbParameter 

Свойство

Описание

DbType

Читает или записывает информацию о "родном" типе данных для источника данных, представленную в виде соответствующего типа данных CLR

Direction

Читает или записывает значение, указывающее направление потока для данного параметра (только ввод, только вывод, двунаправленное движение, предусмотренное возвращение значения)

IsNullable

Читает или записывает значение, являющееся индикатором того, что параметр допускает значения null

ParameterName

Читает или устанавливает имя DbParameter

Size

Читает или устанавливает максимальный размер данных параметра

Value

Читает или устанавливает значение параметра

Для иллюстрации мы модифицируем предыдущий метод InsertNewCar(), чтобы в нем использовались объекты параметра. Вот как может выглядеть соответствующий программный код.

private static void InsertNewCar(SqlConnection cn) {

 …

 // Обратите внимание на 'заполнители' в SQL-запросе.

 string sql = string.Format("Insert Into Inventory" +

  "(CarID, Make, Color, PetName) Values" +

  "(@CarID, @Make, @Color, @PetName)");

 // Наполнение коллекции параметров.

 SqlCommand cmd = new SqlCommand(sql, cn);

 SqlParameter param = new SqlParameter();

 param.ParameterName = "@CarID";

 param.Value = newCarID;

 param.SqlDbType = SqlDbType.Int;

 cmd.Parameters.Add(param);

 param = new SqlParameter();

 param.ParameterName = "@Make";

 param.Value = newCarMake;

 param.SqlDbType = SqlDbType.Char;

 param.Size = 20;

 cmd.Parameters.Add(param);

 param = new SqlParameter();

 param.ParameterName = "@Color";

 param.Value = newCarColor;

 param.SqlDbType = SqlDbType.Char;

 param.Size = 20;

 cmd.Parameters.Add(param);

 param = new SqlParameter();

 param.ParameterName = "@PetName";

 param.Value = newCarPetName;

 param.SqlDbType = SqlDbType.Char;

 param.Size = 20;

 cmd.Parameters.Add(param);

 cmd.ExecuteNonQuery();

}

Хотя при создании параметризованного запроса требуется вводить большой объем программного кода, конечный результат оказывается более выгодным с точки зрения программного использования SQL-операторов. Улучшается также и общая производительность. Вы, конечно, можете использовать предлагаемый подход для всех SQL-запросов, но наиболее полезными параметризованные запросы оказываются при запуске хранимых процедур.

Замечание. Здесь для создания объектов параметров использовались различные свойства. Но следует знать и о том, что объекты параметров поддерживают целый ряд перегруженных конструкторов, также позволяющих установить значения свойств (кроме того, в результате получается более компактный базовый программный код).