Запись времени в SQL C#

Нужно, чтобы при авторизации пользователя параллельно шла запись времени (при авторизации) в таблицу SQL столбца Time_Connect. И при деавторизации тоже записывалась в столбец Time_Disconnect.

Имеется следующий код:

private void mAuth_Click(object sender, EventArgs e)
        {

            String loginUser = authLogin.Text;
            String passUser = authPassword.Text;

            DB db = new DB();

            DataTable table = new DataTable();

            MySqlDataAdapter adapter = new MySqlDataAdapter();

            MySqlCommand command = new MySqlCommand("SELECT * FROM `WorketTableLog` WHERE `Auth_Login` = @uL AND `Auth_Password` = @uP", db.getCon());
            command.Parameters.Add("@uL", MySqlDbType.VarChar).Value = loginUser;
            command.Parameters.Add("@uP", MySqlDbType.VarChar).Value = passUser;

            MySqlCommand insertDate = new MySqlCommand("INSERT INTO `WorketTableLog` `Time_Connect` Values ('" + DateTime.Now + "')", db.getCon());
            MySqlCommand updateDate = new MySqlCommand("UPDATE `WorketTableLog` SET `Time_Connect` = '" + DateTime.Now + "'", db.getCon());
            command.Parameters.Add("@dateTime", MySqlDbType.DateTime).Value = DateTime.Now;
            //insertDate = "UPDATE WorketTableLog SET Time_Connect = '" + DateTime.Now + "'";


            adapter.SelectCommand = updateDate;
            adapter.SelectCommand = insertDate;
            adapter.SelectCommand = command;
            adapter.Fill(table);
            if (table.Rows.Count > 0)
            {
                labelLogin.Visible = false;
                hello.Visible = true;
                labelPassword.Visible = false;
                authLogin.Visible = false;
                authPassword.Visible = false;
                mAuth.Visible = false;
                mExit.Visible = true;
            }
            else
            {
                MessageBox.Show("Неправильный логин или пароль.");
            }
        }

Ответы (1 шт):

Автор решения: Alexander Petrov

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

Далее, я предлагаю убить двух здоровенных зайцев одним запросом Update. Вставляем время пользователю с определённым логином и паролем. Если запрос прошёл успешно, значит такой пользователь есть. Таким образом мы и убедились в его наличии, и данные вставили.

void Login(string login, string pass)
{
    string sql = "UPDATE `WorketTableLog` SET `Time_Connect` = @time WHERE `Auth_Login` = @login AND `Auth_Password` = @pass";

    using (var connection = new MySqlConnection(_connectionString))
    {
        connection.Open();
        using (var command = new MySqlCommand(sql, connection))
        {
            command.Parameters.Add("time", MySqlDbType.DateTime).Value = DateTime.Now;
            command.Parameters.Add("login", MySqlDbType.VarChar).Value = login;
            command.Parameters.Add("pass", MySqlDbType.VarChar).Value = pass;

            int rowsAffected = command.ExecuteNonQuery();
            if (rowsAffected == 1)
            {
                // Успешно вставили время.
                // Это значит в таблице есть пользователь с таким логином и паролем.
            }
            else
            {
                // Неправильный логин или пароль.
                // Или ошибка в работе с БД.
            }
        }
    }
}

При деавторизации, я полагаю, нет смысла проверять пароль. Ведь мы уже знаем, что этот пользователь существует. Просто обновляем в таблице столбец "Time_Disconnect".

void Logout(string login)
{
    string sql = "UPDATE `WorketTableLog` SET `Time_Disconnect` = @time WHERE `Auth_Login` = @login";

    using (var connection = new MySqlConnection(_connectionString))
    {
        connection.Open();
        using (var command = new MySqlCommand(sql, connection))
        {
            command.Parameters.Add("time", MySqlDbType.DateTime).Value = DateTime.Now;
            command.Parameters.Add("login", MySqlDbType.VarChar).Value = login;

            int rowsAffected = command.ExecuteNonQuery();
            if (rowsAffected == 1)
            {
                // Успешно вставили время.
            }
            else
            {
                // Ошибка в работе с БД.
            }
        }
    }
}

А теперь прописные истины:

  • освобождайте ресурсы, оборачивая их в оператор using (или вызывая метод Dispose),
  • используйте параметризованные запросы, это защитит от sql-инъекций.

Желательно переделать код на асинхронный: используйте OpenAsync(), ExecuteNonQueryAsync().

Не храните в БД пароли. Вместо этого храните хеши, причём обязательно с солью. Рекомендую к прочтению: Adding Salt to Hashing: A Better Way to Store Passwords.


Ещё замечание. Я не вижу большого смысла в таком хранении времени. Ведь оно перетирается при каждом новом входе юзера.
Вероятно, вам следует создать отдельную историческую таблицу (связанную через внешний ключ с этой), в которой будет храниться время за все сеансы пользователя.

→ Ссылка