Сравнение ввода текстового поля с sql-запросом

#c# #sql #database

#c# #sql #База данных

Вопрос:

Вот мой код на c #, в нем говорится: «Для строки / столбца не существует данных». как я могу улучшить этот код, чтобы он работал правильно?

 db = new OleDbConnection();
db.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data source="   fileName;
db.Open();

string sql = "SELECT * FROM GroupNameNS WHERE GroupName = '"   Groupnametxt.Text.Trim()   "'";

cmd = new OleDbCommand(sql, db);
rdr = cmd.ExecuteReader();

if (Groupnametxt.Text.Trim() == (string)rdr["GroupName"])
{
  MessageBox.Show("Group Name taken, please try another name", "Error in Name", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
  membernumber1.ReadOnly = true;
}
else
{
  sql = "INSERT INTO GroupNameNS VALUES ('"   Groupnametxt.Text.Trim()   "')";
  membernumber1.ReadOnly = false;
  cmd = new OleDbCommand(sql, db);
  rdr = cmd.ExecuteReader();
}
  

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

1. «… или что-то в этом роде»? Сообщите нам точную ошибку, если вам нужна помощь… Вы запрашиваете электронную таблицу Excel?

2. «Или что-то в этом роде»? Если вы хотите, чтобы люди помогли вам с ошибкой, пожалуйста, хотя бы найдите время, чтобы задокументировать точное сообщение об ошибке. Кроме того, вам, вероятно, было бы неплохо поискать в Google «sql-инъекционная атака».

3. Пожалуйста, предоставьте дополнительную информацию. «Или что-то в этом роде» не помогает нам определить проблему. У вас есть трассировка стека? Ваш приведенный выше код на данный момент также очень удобен для SQL-инъекций. Вам следует рассмотреть возможность использования параметров SqlParameters для ваших запросов. Вам не нужно проверять, равен ли Groupnametxt тому, что содержит ваш DataReader, потому что запрос уже выполнил это сравнение и фильтрацию для вас.

Ответ №1:

Вам нужно вызвать .Read() для вашего объекта Reader для увеличения по строкам вашего результирующего набора.

 rdr.Read();
  

// Обратите внимание, что это вернет false, если больше нет записей для чтения, поэтому оно обычно используется внутри if оператора или while цикла and

Вы можете изменить свое if (Groupnametxt.Text.Trim() == (string)rdr["GroupName"]) значение на if(rdr.Read()) , потому что, если в вашей таблице есть хотя бы 1 запись с этим GroupName значением, она вернет true .

             if (rdr.Read())
            {
                MessageBox.Show("Group Name taken, please try another name", "Error in Name", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                membernumber1.ReadOnly = true;
                rdr.Close();
            }
            else
            {
                rdr.Close();
                sql = "INSERT INTO GroupNameNS VALUES ('"   Groupnametxt.Text.Trim()   "')";
                membernumber1.ReadOnly = false;
                cmd = new OleDbCommand(sql, db);
                cmd.ExecuteNonQuery();
            }
  

Я также изменил пару других вещей: не забудьте закрыть свой объект Reader после его использования. И использовать ExecuteNonQuery() для INSERT

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

1. Уязвим для атаки с использованием SQL-инъекций. Следует использовать параметр SQL для имени группы.

Ответ №2:

Вот некоторые дополнительные изменения для обеспечения надлежащей очистки с помощью ключевого слова using и добавления параметра для groupname в качестве наилучшей практики.

 using(OleDbConnection db = new OleDbConnection())
{
    db.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data source="   fileName; 
    db.Open(); 

    string groupName = groupName.Text.Trim();   
    string sql = "SELECT * FROM GroupNameNS WHERE GroupName = '@groupname'"; 

    using(OleDbCommand cmd = new OleDbCommand(sql, db))
    {
        cmd.Parameters.AddWithValue("@groupname", groupName);

        using(OleDbDataReader rdr = cmd.ExecuteReader())
        {       
            if (rdr.Read()) 
            { 
                MessageBox.Show("Group Name taken, please try another name", "Error in Name", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); 
                membernumber1.ReadOnly = true; 
            } 
            else 
            { 
                sql = "INSERT INTO GroupNameNS VALUES ('@groupname')"; 
                cmd.CommandText = sql;              
                cmd.ExecuteNonQuery();
                membernumber1.ReadOnly = false;         
            } 
        }
    }
}