Данное руководство устарело. Актуальное руководство: по ADO.NET и работе с базами данных в .NET 6
Ранее для отправки запросов мы напрямую добавляли данные в выражение 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.