Параметризация запросов

Данное руководство устарело. Актуальное руководство: по ADO.NET и работе с базами данных в .NET 6

Последнее обновление: 31.10.2015

Ранее для отправки запросов мы напрямую добавляли данные в выражение sql. Например, для отправки запроса на добавление данных в БД применялось следующее выражение:

string sqlExpression = String.Format("INSERT INTO Users (Name, Age) VALUES ('{0}', {1})", name, age);

В данном случае предполагается, что значения для переменных name и age вводит пользователь.

Что если переменная name получит следующее значение:

name = "Tom',10);INSERT INTO Users (Name, Age) VALUES('Hack";

В этом случае sql-выражение в итоге будет выглядеть следующим образом:

INSERT INTO Users (Name, Age) VALUES ('Tom',10);INSERT INTO Users (Name, Age) VALUES('Hack,{1})";

В итоге в базу данных будет добавлено два объекта. Это относительно безобидный вид подмены sql-выражения, но реальные возможности встраивания зловредных скриптов таковы, что можно вообще потерять данные в БД, если предоставить пользователям подобным образом добавлять данные.

Чтобы выйти из этой ситуации, в sql-командах используются параметры:

string connectionString = @"Data Source=.\SQLEXPRESS;Initial Catalog=usersdb;Integrated Security=True";
int age = 23;
string name = "T',10);INSERT INTO Users (Name, Age) VALUES('H";
string sqlExpression = "INSERT INTO Users (Name, Age) VALUES (@name, @age)";
using (SqlConnection connection = new SqlConnection(connectionString))
{
    connection.Open();
    SqlCommand command = new SqlCommand(sqlExpression, connection);
	// создаем параметр для имени
    SqlParameter nameParam = new SqlParameter("@name", name);
	// добавляем параметр к команде
    command.Parameters.Add(nameParam);
	// создаем параметр для возраста
	SqlParameter ageParam = new SqlParameter("@age", age);
	// добавляем параметр к команде
    command.Parameters.Add(ageParam);

    int number = command.ExecuteNonQuery();
    Console.WriteLine("Добавлено объектов: {0}", number); // 1
}

Для определения параметров используется объект SqlParameter. Этот объект имеет ряд конструкторов, но в данном случае передается название параметра и его значение. Причем название параметров начинается со знака @ и должно совпадать с тем названием, которое используется в sql-выражении (то есть в "INSERT INTO Users (Name, Age) VALUES (@name, @age)"). После определения параметра он добавляется в коллекцию параметров команды.

При выполнении команды на место параметров в sql-выражении подставляются их значения. При этом не важно, что параметр @name в значении определяет еще одну команду INSERT - все его значение будет добавлено в столбец name в таблице Users.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850