Как бы я использовал 2 sql команды с 1 читателем? - PullRequest
0 голосов
/ 14 января 2020

Я пытаюсь удалить токен из моей SQL базы данных после его использования.

            MySqlCommand cmdSel = new MySqlCommand("SELECT * FROM tokens WHERE token = " + int.Parse(passbox.Text), dbCon);
            MySqlDataReader dbRead = cmdSel.ExecuteReader();
            if (dbRead.Read())
            {
                int sqlkey = int.Parse(dbRead["token"].ToString()); 
                if (keyint == sqlkey)
                {
                    using (MySqlCommand delTok = new MySqlCommand("DELETE FROM tokens WHERE token = " + keyint, dbCon))
                    {
                        delTok.ExecuteNonQuery(); //MAIN PROBLEM HERE.
                        /*
                        MySql.Data.MySqlClient.MySqlException: 'There is already an open DataReader associated with this Connection which must be closed first.'
                        */
                        //ERROR ^^^^^^
                    }
                    try
                    {
                        dbCon.Close();
                        loading loading = new loading();
                        loading.Show();
                        this.Hide();
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                        return;
                    }
                }
            }

мне нужно закрыть DataReader или есть какой-то другой способ, и как мне закрыть читатель? Я хочу удалить токен, если if keyint - это заявление sqlkey, верно / сделано. Ошибка отображается только после того, как я пытаюсь выполнить скрипт для оператора if. "Токен" - это int (10)

Ответы [ 3 ]

2 голосов
/ 14 января 2020

Подключение позволяет только один открытый читатель.

Вы можете избавиться от проблемы с двумя устройствами чтения данных, выполнив только один запрос на «удаление».
Если токен найден, запрос удалит его, если нет, запрос ничего не сделает.

using (var connection = new MySqlConnection("connection-string"))
using (var command = connection.CreateCommand())
{
    command.CommandText = "DELETE FROM tokens WHERE token = @token";
    var token = new MySqlParameter
    {
        ParameterName = "@token",
        MySqlDbType = MySqlDbType.Int32,
        Value = int.Parse(passbox.Text)
    };
    command.Parameters.Add(token);

    connection.Open();
    command.ExecuteNonQuery();                
}

Не пытайтесь «сохранить» соединение, просто избавьтесь от предыдущего и создавайте новое каждый раз, когда вам нужно. ADO. NET в фоновом режиме эффективно повторно использует уже открытые фактические соединения.

Используйте параметры sql для передачи значений в запрос. Параметры Sql защищают от внедрения sql и улучшают производительность запросов sql, повторно используя предварительно скомпилированные планы запросов.

0 голосов
/ 14 января 2020

Вы должны сначала закрыть читатель , чтобы выполнить другую команду. Кроме того, вы не можете выполнить команду, пока Db reader читает данные. Таким образом, вы можете использовать функцию или выполнить команду после закрытия считывателя.


int sqlkey=0;

using(MySqlCommand cmdSel = new MySqlCommand("SELECT * FROM tokens WHERE token = " + int.Parse(passbox.Text), dbCon))

 {

           MySqlDataReader dbRead = cmdSel.ExecuteReader();
           if (dbRead.Read())
             {
               sqlkey = int.Parse(dbRead["token"].ToString()); 

               }

       reader.close();

  }

      if (keyint == sqlkey)
               {
                   using (MySqlCommand delTok = new MySqlCommand("DELETE FROM tokens WHERE token = " + keyint, dbCon))
                      {

                       delTok.ExecuteNonQuery(); 


                   try
                   {
                       dbCon.Close();
                       loading loading = new loading();
                       loading.Show();
                       this.Hide();
                   }
                   catch (Exception ex)
                   {
                       MessageBox.Show(ex.Message);
                       return;
                   }
                 }
}

0 голосов
/ 14 января 2020

Сделал новый приватный void и вызвал его с токеном после оператора if.

        private void delQuery(int token)
        {
            //SETUP CONNECTION
            MySqlConnection dbConn = new MySqlConnection("some connection");

            //OPEN CONNECTION
            dbConn.Open();

            //DELETE TOKEN
            MySqlCommand delcmd = new MySqlCommand("DELETE FROM tokens WHERE token = " + token, dbConn);
            MySqlDataReader dbReader = delcmd.ExecuteReader();
            dbReader.Read();

            //CLOSE CONNECTION
            dbConn.Close();
        }

вызвал его, используя:

if (dbRead.Read())
            {
                int sqlkey = int.Parse(dbRead["token"].ToString());
                if (keyint == sqlkey)
                {
                    dbCon.Close();
                    delQuery(keyint);
                }
            }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...