2012-01-19 7 views
3

Я продолжаю получать ошибку, которую я не понимаю. Должен объявить скалярную переменную «@varname»Должен объявить скалярную переменную «@UserName»

Десятки часов исследований, попробовал несколько решений без успеха.

Моя цель - создать страницу входа, в которой используются 2 текстовых поля, и кнопку, где он проверяет, выходит ли пользователь на основе информации, хранящейся в базе данных Sql.

Это где я думаю, что проблема исходит от:

private bool DBConnection(string userName, string password) 
{ 
    SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString); 

    //string cmdString = ("SELECT UserName, Password FROM Users WHERE UserName ='" + userName + 
    //     "'AND Password ='" + password + "'");   //REMOVED AS THIS IS PRONE TO SQL INJECTIONS 

    string cmdString = ("SELECT * FROM Users WHERE UserName = @uname AND Password = @pw"); 

    SqlCommand cmd = new SqlCommand(cmdString, conn); 

    cmd.Parameters.Add("uname", SqlDbType.VarChar).Value = userName; 
    cmd.Parameters.Add("pw", SqlDbType.VarChar).Value = password; 

    DataSet loginCredentials = new DataSet(); 
    SqlDataAdapter dataAdapter; 

    try 
    { 
     if (conn.State.Equals(ConnectionState.Closed)) 
     { 
      conn.Open(); 

      dataAdapter = new SqlDataAdapter(cmdString, conn); 
      dataAdapter.Fill(loginCredentials); 

      conn.Close(); 

      if (loginCredentials != null) 
      { 
       if (loginCredentials.Tables[0].Rows.Count > 0) 
       { 
        return true; 
       } 
       else 
       { 
        lblMessage.Text = "Incorrect Username or Password"; 
        lblMessage.Visible = true; 
       } 
      } 
     } 
    } 
    catch (Exception err) 
    { 
     lblMessage.Text = err.Message.ToString() + " Error connecting to the Database // " + cmd.Parameters.Count; 
     lblMessage.Visible = true; 
     return false; 
    } 

    return false; 
} 

конкретно где "dataAdapter.Fill (loginCredentials);" выполняется.

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

скриншот ошибки ниже: Error screenshot.

любая помощь будет оценена.

+0

вместо 'DataAdapter = новый SqlDataAdapter (cmdString, свя); ' use' dataAdapter.SelectCommand = cmd; ' –

+0

Пожалуйста, не публикуйте свою ошибку как ссылку на другое место. Пока что он недоступен. Поэтому он не позволяет кому-либо его просматривать. – Richard

+1

@ Рихард Хмм. Ссылка работает для меня, но вложит img в вопрос. Что касается оправдания, то в тот же день вам нужна определенная репутация, прежде чем вы сможете получить изображения в вопросах :) –

ответ

2

Редактировать: Вы должны передать sqlcommand в dataAdapter, потому что в вашем случае sqlcommand (cmd) имеет больше информации, чем простой командный текст и строку соединения. Ваш код может выглядеть следующим образом:

private bool DBConnection(string userName, string password) 
{ 
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString); 

//string cmdString = ("SELECT UserName, Password FROM Users WHERE UserName ='" + userName + 
//     "'AND Password ='" + password + "'");   //REMOVED AS THIS IS PRONE TO SQL INJECTIONS 

string cmdString = ("SELECT * FROM Users WHERE UserName = @uname AND Password = @pw"); 

SqlCommand cmd = new SqlCommand(cmdString, conn); 

cmd.Parameters.Add("uname", SqlDbType.VarChar).Value = userName; 
cmd.Parameters.Add("pw", SqlDbType.VarChar).Value = password; 

DataSet loginCredentials = new DataSet(); 
SqlDataAdapter dataAdapter; 

try 
{ 
    if (conn.State.Equals(ConnectionState.Closed)) 
    { 
     conn.Open(); 

     dataAdapter = new SqlDataAdapter(cmd); 
     dataAdapter.Fill(loginCredentials); 

     conn.Close(); 

     if (loginCredentials != null) 
     { 
      if (loginCredentials.Tables[0].Rows.Count > 0) 
      { 
       return true; 
      } 
      else 
      { 
       lblMessage.Text = "Incorrect Username or Password"; 
       lblMessage.Visible = true; 
      } 
     } 
    } 
} 
catch (Exception err) 
{ 
    lblMessage.Text = err.Message.ToString() + " Error connecting to the Database // " + cmd.Parameters.Count; 
    lblMessage.Visible = true; 
    return false; 
} 

return false; 
} 
+0

У меня была такая же проблема, и после тонны исследований я наткнулся на ваш ответ, и это работает. Любая идея, почему вызов нового SqlDataAccess (cmdString, conn) не работает в этом конкретном сценарии? – makoshichi

+0

Не имеет прямого отношения к вопросу здесь, но у меня была аналогичная проблема с OleDbDataAdapter, и результат поиска привел сюда. Для OleDb параметры в тексте SQL должны использовать? символ в качестве позиционного заполнителя.Если текст SQL имеет такие параметры, как @paramname в тексте SQL и с использованием SQL Server, вы можете получить ту же ошибку «Должен объявить скалярную переменную» – Rattle

+1

«Заменить код следующим образом:« очень бесполезно для людей, пытающихся понять проблему, особенно когда блок кода настолько велик. – Goose

2
cmd.Parameters.Add("@uname", SqlDbType.VarChar).Value = userName; 

Обратите внимание на @ перед неисполнением.

+0

@ символ в параметрах не является обязательным. – Mubarek

3

Вы должны пройти cmd до конструктора SqlDataAdapter вместо cmdString и conn объектов.

2

Помимо описанной ниже ошибки (или вверху здесь)), вы передаете командную строку и соединение с адаптером данных, но вы заполняете параметры по команде, которую вы не используете.), поэтому у вас есть несколько ошибок ...

0

Самое главное в том, что первая проверка, если некоторое значение присваивается конкретной переменной т.е.

cmd.parameter.add(@YOUR_VARIABLE, sqlDbtype.TYPE).value = ValueYouwantToGIveToThatVariable; 
Смежные вопросы