Продолжайте получать System.Data.SqlClient.SQLException: «Неправильный синтаксис рядом «;».»

#c# #sql-server #visual-studio

#c# #sql-сервер #visual-studio

Вопрос:

Я прочитал многие вопросы и ответы, представленные на этом форуме по этому вопросу, применил множество различных методов и столько раз менял свой код, что даже не помню оригинал.

Я продолжаю получать эту ошибку в следующей строке:

 SqlDataReader dr;  

ошибка в том, что

System.Data.SqlClient.SQLException: «Неправильный синтаксис рядом «;».»

Я полный нуб в этом, и я самоучка, поэтому приношу свои извинения.

Это находится в файле App.Config

 lt;connectionStringsgt;  lt;add name="ConnectionString" connectionString="Data Source=(LocalDB)MSSQLLocalDB;Initial Catalog=SolAquaMasterDdata;Integrated Security=True"  providerName="System.Data.SqlClient" /gt; lt;/connectionStringsgt;  

Мой код в основной форме:

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.Data.SqlClient; using System.Data; using System.Configuration;  namespace SolTry {  /// lt;summarygt;  /// Interaction logic for MainWindow.xaml  /// lt;/summarygt;  public partial class MainWindow : Window  {  SqlConnection conn = new SqlConnection();  SqlCommand cmd = new SqlCommand();    public MainWindow()  {  InitializeComponent();  conn.ConnectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString.ToString();  }   private void BtnLogin_Click(object sender, RoutedEventArgs e)  {  string User = txtUsername.Text;  string Pass = txtPassword.Password;   string str1 = "Please enter a valid Username and Password.";  string str2 = "The credentials entered do not match any registed users.";  string str3 = "These login credentials are correct.";   conn.Open();  cmd.Connection = conn;  SqlDataReader dr;  cmd.CommandText = ("SELECT Status, UserName, Password FROM tblUsers WHERE UserName = @Username and Password = @Password;");  using (conn)  {  //help add parameterization - missing   dr = cmd.ExecuteReader();   if ((string.IsNullOrEmpty(User)) amp;amp; (string.IsNullOrEmpty(Pass)))  {  MessageBox.Show(str1, "NO CREDENTIALS ENTERED", MessageBoxButton.OK, MessageBoxImage.Error);  }   if ((string.IsNullOrEmpty(User)) == false amp;amp; (string.IsNullOrEmpty(Pass)) == false)  {  if (dr.HasRows.Equals(true))  {  MessageBox.Show(str3, "LOGIN SUCCESSFUL", MessageBoxButton.OK, MessageBoxImage.Information);  }   else if (dr.HasRows == false)  {  MessageBox.Show(str2, "INVALID CREDENTIALS", MessageBoxButton.OK, MessageBoxImage.Error);  }  }  }  conn.Close();  }   private void ExitApp(object sender, RoutedEventArgs e)  {  Application.Current.Shutdown();  }   protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)  {  base.OnMouseLeftButtonDown(e);  DragMove();  }  } }  

Что бы я ни пытался, я все равно терплю неудачу.

Все, что я пытаюсь сделать, это нажать кнопку формы входа в систему, чтобы убедиться, что имя пользователя и пароль указаны правильно в tblUsers, а затем проверить, что статус «true» или 1

Пожалуйста, покажите мне, как параметризовать sql

Комментарии:

1. Нет, SqlDataReader dr; возможно, это не та строка, в которой вы получаете эту конкретную ошибку.

2. В ГДЕ отсутствует закрывающая скобка. Должно быть : txt.Пароль);»);

3. Запрос также должен поместить текстовые значения txt.Password и txt.Username в параметры и добавить эти параметры в команду.

4. Тот факт, что вы хотите передать значение txt.Password , настоятельно указывает на то, что вы храните пароли в виде обычного текста. Это серьезный недостаток в системе безопасности. Всегда солируйте и хэшируйте свои пароли.

5. @jdweng Я бы предположил, что в нем не отсутствует один, у него есть посторонний; WHERE его вообще не нужно заключать в круглые скобки.

Ответ №1:

Эта строка кода содержит несоответствующие скобки в тексте запроса в кавычках.

 cmd.CommandText = ("SELECT Status, UserName, Password   FROM tblUsers WHERE(UserName = txt.Username   and Password = txt.Password;");  

После » ГДЕ » есть открытая скобка, и в процитированном тексте нет закрывающей скобки. Вот почему вы получаете исключение SQL. Вы можете либо удалить открывающую скобку, либо добавить закрывающую скобку.

Кроме того, вам необходимо использовать параметры для передачи значений имени пользователя и пароля. Строки txt.Username и txt.Password не будут иметь никакого значения для SQL-сервера.

Ответ №2:

Существует много проблем с вашим существующим кодом.

  • В первую очередь, вы пытаетесь ссылаться на объекты C# из SQL. Вы не можете этого сделать, так как сервер вообще не видит ваш клиентский код. Вместо этого используйте правильную параметризацию.
  • У вас была отсутствующая/дополнительная скобка
  • Вам необходимо создать и разместить свой объект подключения, команды и считывателя с using блоками в месте использования. Тогда вам не нужно явно закрывать, using он закроет его за вас.
  • Не блокируйте поток с помощью окна сообщения, пока соединение открыто
  • На самом деле нет необходимости использовать считыватель, потому что вы хотите проверить наличие только одной строки. Просто SELECT 1 и используйте cmd.ExecuteScalar()
  • Не храните и не передавайте пароли в виде обычного текста. Хэшируйте пароль в клиенте и передайте хэш на сервер для проверки.
 if ((string.IsNullOrEmpty(User)) amp;amp; (string.IsNullOrEmpty(Pass))) {  MessageBox.Show(str1, "NO CREDENTIALS ENTERED", MessageBoxButton.OK, MessageBoxImage.Error);  return; }  bool isMatch;  const string query = @" SELECT 1 FROM tblUsers u WHERE u.UserName = @Username  and u.PasswordHash = @PasswordHash; "; using (var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString.ToString())) using (var cmd = new SqlCommand(query, conn)) {  cmd.Parameters.Add("@UserName", SqlDbType.NVarchar, 250).Value = txt.Username;  cmd.Parameters.Add("@PasswordHash", SqlDbType.Binary, 32).Value = YourPasswordHashFunctionHere(txt.Password);  conn.Open();  isMatch = ((int?)cmd.ExecuteScalar()) == 1; }  if (isMatch) {  MessageBox.Show(str3, "LOGIN SUCCESSFUL", MessageBoxButton.OK, MessageBoxImage.Information); } else {  MessageBox.Show(str2, "INVALID CREDENTIALS", MessageBoxButton.OK, MessageBoxImage.Error); }  

Комментарии:

1. Привет, ребята, спасибо вам всем огромное, мне очень жаль, должно быть, так неприятно иметь дело с такими нубами, как я, но, честно говоря, вы, ребята, так помогли, и @Charlieface спасибо вам за изменение моего кода. Я использовал его и ввел, но получил ошибку, поэтому просто изменил и добавил одну или 2 вещи, и, к счастью, это сработало, хахахаха. Я не знаю, как хэшировать/шифровать пароли или использовать соль в SQL-сервере, поэтому мне пришлось согласиться с тем, что форма блокирует пароль. Я собираюсь попробовать найти кое-что по этой теме и изучить ее. большое вам всем спасибо.

Ответ №3:

вы не отправляете в команду никаких параметров. параметризуйте свой запрос, и sql будет работать

 cmd.CommandType = System.Data.CommandType.StoredProcedure;  cmd.CommandText = ("SELECT Status, UserName, Password FROM tblUsers WHERE UserName = @Username and Password = @Password;");   cmd.Parameters.Add("@UserName", SqlDbType.Varchar, 255).Value = txt.Username;  cmd.Parameters.Add("@Password", SqlDbType.Varchar, 255).Value = txt.Password;   dr = cmd.ExecuteReader();  

Выполните шифрование и расшифровку пароля в базе данных с помощью хэшбайта. Затем клиент использует только текст. Не делайте хеширования на стороне клиента. пусть все будет просто.

 See. https://www.mssqltips.com/sqlservertip/4037/storing-passwords-in-a-secure-way-in-a-sql-server-database/   Hashbytes  

Комментарии:

1. Это также защищает ваше приложение от sql-инъекций. поэтому, даже если это не соответствует вашим потребностям, вы должны это сделать. @ТравО