Вопрос о хранимых процедурах и командах sql в коде - PullRequest
0 голосов
/ 06 июня 2011

Я новичок в SQL, и я пытаюсь делать манипуляции с данными с помощью встроенных / в коде SQL команд.Тем не менее, я знаю, что вам нужно писать много кода, иногда в trans-sql .. Когда я пишу это, тогда люди говорят, что он подвергается SQL-инъекциям.Тогда я не знаю, что делать ...

Что мне было бы легче сделать, учитывая, что я не специалист по программированию баз данных.Должен ли я использовать хранимые процедуры или встроенный текст.И как передать параметры хранимым процедурам?(например, если у меня есть ввод из текстового поля).

Ответы [ 3 ]

1 голос
/ 06 июня 2011

Давайте рассмотрим пример для входа в систему пользователя:

нормальный запрос будет выглядеть примерно так:

SELECT name, lastLogin 
FROM [tblUsers] 
where username = 'balexandre' AND password = 'veryhard';

, если поместить это в код, это будет kind'a

using (SqlConnection connection = new SqlConnection(connectionString)) { 

    DataSet userDataset = new DataSet(); 

    string query = "SELECT name, lastLogin FROM [tblUsers] where username = '" + txtUser.Text.Trim() + "' AND password = '" + txtPassword.Text.Trim() + "'";

    SqlDataAdapter myCommand = new SqlDataAdapter(query, connection);
    myCommand.Fill(userDataset); 
}

Но это не помешает SQL-инъекции, попробуйте представить, что произойдет, если я добавлю в текстовое поле имени пользователя что-то вроде % и в текстовом поле пароля что-то вроде ' OR 1=1-- или просто ' OR 1=1-- в имени пользователятекстовое окно.Это будет действительно так: 1 на самом деле равен 1, и я буду зарегестрирован ...

пройденный запрос будет выглядеть так:

SELECT name, lastLogin 
FROM [tblUsers] 
where username = '' OR 1=1 --' AND password = '';

Вы понимаете, верно?

Но если мы будем использовать параметры в нашем запросе , этого никогда не произойдет, например:

using (SqlConnection connection = new SqlConnection(connectionString)) { 

    DataSet userDataset = new DataSet(); 

    string query = "SELECT name, lastLogin FROM [tblUsers] where username = @username AND password = @password";
    SqlDataAdapter myCommand = new SqlDataAdapter(query, connection);

    myCommand.SelectCommand.Parameters.Add("@username", SqlDbType.VarChar, 30); 
    myCommand.SelectCommand.Parameters["@username"].Value = txtUser.Text.Trim(); 

    myCommand.SelectCommand.Parameters.Add("@password", SqlDbType.VarChar, 30); 
    myCommand.SelectCommand.Parameters["@password"].Value = txtPassword.Text.Trim(); 

    myCommand.Fill(userDataset); 
}

То же самое, если вы хотите использовать Процедуры хранения :

using (SqlConnection connection = new SqlConnection(connectionString)) { 

    DataSet userDataset = new DataSet(); 

    string query = "spGetUser";
    SqlDataAdapter myCommand = new SqlDataAdapter(query, connection);
    myCommand.SelectCommand.CommandType = CommandType.StoredProcedure; 

    myCommand.SelectCommand.Parameters.Add("@username", SqlDbType.VarChar, 30); 
    myCommand.SelectCommand.Parameters["@username"].Value = txtUser.Text.Trim(); 

    myCommand.SelectCommand.Parameters.Add("@password", SqlDbType.VarChar, 30); 
    myCommand.SelectCommand.Parameters["@password"].Value = txtPassword.Text.Trim(); 

    myCommand.Fill(userDataset); 
}

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

Одна из наиболее часто используемых баз данных ORM - NHibernate и ADO Entity Framework .

Вы можете использовать запросы LINQ с этим, и ваш вызов будет выглядеть так:

public User GetUser(string username, string password)
{
    return _db.Users.FirstOrDefault(x => x.User == username && x.Password == password);
}

и если у вас была процедура хранения, она такая же (пример ниже просто показывает другой способ ее вызова)

public User GetUser(string username, string password)
{
    return (from u in _db.spGetUser(username, password)
            select u).FirstOrDefault();                
}

И вы ненадо подумать, кэширование , инъекция , параллелизм и т. д. *

0 голосов
/ 06 июня 2011

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

0 голосов
/ 06 июня 2011

Вам не нужно использовать хранимые процедуры, чтобы избежать «SQL-инъекций»;вам просто нужно использовать параметризованные запросы (которые, очевидно, являются хранимыми процедурами).

Учебник по ADO.NET для станции C #

Использование параметров с SqlCommand иХранимая процедура

Пример «Голые кости» (не скомпилированы):

string connectionString = "Server=(local);DataBase=Northwind;Integrated Security=SSPI";

using (SqlConnection conn = new SqlConnection(connectionString))
{
     conn.Open(); 
     SqlCommand cmd  = new SqlCommand("MyStoredProcName_CustOrderHist", conn);
     cmd.CommandType = CommandType.StoredProcedure;

     cmd.Parameters.Add(new SqlParameter("@CustomerID", custId));

     // execute the command
     SqlDataReader rdr = cmd.ExecuteReader();

     while (rdr.Read())
     {
          // do something with results
     }


     conn.close;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...