Member 12801143 Ответов: 4

Заполните текстовое поле увеличенным значением из базы данных access в C#


Привет,


Я создал приложение на языке C # для запроса и вставки базы данных продуктов. Однако я здесь с небольшим сомнением, и если кто-нибудь может мне помочь, я сразу же благодарю вас.

Ниже приводится следующее:

У меня есть форма для вставки данных в базу данных, созданную в MS Access 2007, со значениями ссылки, номера продажи, кода клиента, имени клиента, количества и номера позиции в архиве;

Как я могу сделать так, чтобы вместо ручного ввода номера позиции в архиве в текстовое поле он мог быть автоматически заполнен новой позицией в архиве? Например, мой последний вставленный продукт имеет позицию 50 в архиве, новый автоматически будет иметь номер 51 и так далее ... и этот номер должен автоматически появиться в текстовом поле, чтобы пользователь знал, каков номер нового зарегистрированного продукта.


Спасибо,

Что я уже пробовал:

Вот мой код до настоящего момента:

private void btn_save_Click(object sender, EventArgs e)
    {
        OleDbConnection con = new OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=product.accdb");
        OleDbCommand check_sn = new OleDbCommand("SELECT COUNT(*) FROM [product] WHERE ([sn] = @sn)", con);
        OleDbCommand check_reference = new OleDbCommand("SELECT COUNT(*) FROM [product] WHERE ([reference] = @ref)", con);
        OleDbCommand check_number = new OleDbCommand("SELECT COUNT(*) FROM [product] WHERE ([number] = @num)", con);

        con.Open();
        check_reference.Parameters.AddWithValue("@ref", textBox_ref.Text);
        check_sn.Parameters.AddWithValue("@sn", textBox_sn.Text);
        check_number.Parameters.AddWithValue("@num", textBox_num.Text);

        int refExist = (int)check_reference.ExecuteScalar();
        int SNExist = (int)check_sn.ExecuteScalar();
        int numExist = (int)check_number.ExecuteScalar();


        if (refExist > 0)
        {
            MessageBox.Show("A product with this reference already exists....!");
        }
        else if (SNExist> 0)
        {
            MessageBox.Show("A product with this sale number already exists....!");
        }
        else if (numExist > 0)
        {
            MessageBox.Show("A product with this archive number already exists....!");
        }
        else
        {
            try
            {
                String reference = textBox_ref.Text.ToString();
                String sn = textBox_ov.Text.ToString();
                String cod_client = textBox_cod.Text.ToString();
                String client = textBox_cliente.Text.ToString();
                String qtd = textBox_qtd.Text.ToString();
                String number = textBox_num.Text.ToString(); //This will be the incremented number

                String my_querry = "INSERT INTO product(reference,sn,cod_client,client,qtd,number)VALUES('" + reference + "','" + sn + "','" + cod_client + "','" + client + "','" + qtd + "','" + number + "')";
                OleDbCommand cmd = new OleDbCommand(my_querry, con);
                cmd.ExecuteNonQuery();

                MessageBox.Show("Data saved successfully...!");

            }
            catch (Exception ex)
            {
                MessageBox.Show("Failed due to" + ex.Message);
            }
            finally
            {

                con.Close();
            }
            cleanTextBoxes(this.Controls);
        }
    }



    private void search_btn_Click(object sender, EventArgs e)
    {
        Form search = new Form_search();

        search.Show();

        this.Hide();
    }
}

Richard Deeming

Используется ли база данных только одним человеком одновременно?

Если нет, то значение, которое вы показываете, вероятно, будет неверным.

Richard Deeming

Также:

String my_querry = "INSERT INTO product(reference,sn,cod_client,client,qtd,number)VALUES('" + reference + "','" + sn + "','" + cod_client + "','" + client + "','" + qtd + "','" + number + "')";

Ваш код уязвим для SQL-инъекция[^]. НИКОГДА используйте конкатенацию строк для построения SQL-запроса. ВСЕГДА используйте параметризованный запрос.

Все, что вы хотели знать о SQL-инъекции (но боялись спросить) | Трой Хант[^]
Как я могу объяснить SQL-инъекцию без технического жаргона? | Обмен Стеками Информационной Безопасности[^]
Шпаргалка по параметризации запросов | OWASP[^]

4 Ответов

Рейтинг:
1

OriginalGriff

Используйте поле IDENTITY или "auto number" в БД и позвольте ему обрабатывать последовательные значения - это опасная идея "предварительно назначать" инкрементные значения в вашем коде презентации, так как это может привести к некоторым неприятным ошибкам в производстве, которые трудно найти, невозможно надежно дублировать и невероятно трудно исправить.

И Ричард абсолютно прав: никогда не объединяйте строки для построения SQL-команды. Это оставляет вас широко открытыми для случайной или преднамеренной атаки SQL-инъекции, которая может уничтожить всю вашу базу данных. Вместо этого всегда используйте параметризованные запросы.

Когда вы объединяете строки, вы вызываете проблемы, потому что SQL получает такие команды, как:

SELECT * FROM MyTable WHERE StreetAddress = 'Baker's Wood'
Цитата, добавленная пользователем, завершает строку в том, что касается SQL, и вы получаете проблемы. Но могло быть и хуже. Если я приду и наберу вместо этого: "x';DROP TABLE MyTable;--", то SQL получит совсем другую команду:
SELECT * FROM MyTable WHERE StreetAddress = 'x';DROP TABLE MyTable;--'
Которые SQL видит как три отдельные команды:
SELECT * FROM MyTable WHERE StreetAddress = 'x';
Совершенно правильный выбор
DROP TABLE MyTable;
Вполне допустимая команда "удалить таблицу"
--'
А все остальное-это комментарии.
Так оно и происходит: выбирает любые совпадающие строки, удаляет таблицу из базы данных и игнорирует все остальное.

Поэтому всегда используйте параметризованные запросы! Или будьте готовы часто восстанавливать свою БД из резервной копии. Вы ведь регулярно делаете резервные копии, не так ли?


Рейтинг:
1

Patrice T

Как вы можете иметь в одном и том же фрагменте кода SQL-команду, безопасную для инъекции, и другую, подлежащую инъекции?

String my_querry = "INSERT INTO product(reference,sn,cod_client,client,qtd,number)VALUES('" + reference + "','" + sn + "','" + cod_client + "','" + client + "','" + qtd + "','" + number + "')";

Никогда не создавайте SQL-запрос путем объединения строк. Рано или поздно вы сделаете это с помощью пользовательских вводов, и это откроет дверь к уязвимости под названием "SQL-инъекция", она опасна для вашей базы данных и подвержена ошибкам.
Одна кавычка в имени - и ваша программа выйдет из строя. Если пользователь вводит имя, например "Брайан О'Коннер", может привести к сбою вашего приложения, это уязвимость SQL-инъекции, и сбой-это наименьшая из проблем, вредоносный пользовательский ввод, и он продвигается к командам SQL со всеми учетными данными.
SQL-инъекция - Википедия[^]
SQL-инъекция[^]
Атаки SQL-инъекций на примере[^]
PHP: SQL-инъекция - руководство пользователя[^]
Шпаргалка по предотвращению инъекций SQL - OWASP[^]
Как я могу объяснить SQL-инъекцию без технического жаргона? - Обмен Стеками Информационной Безопасности[^]


Рейтинг:
0

CHill60

Как уже указывал @OriginalGriff, ваше поле ID в таблице базы данных должно быть полем AutoNumber. Таким образом, доступ автоматически увеличит Ваш идентификатор для вас, и если есть более одного пользователя, вы не получите дубликатов идентификаторов.

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

В вскоре удаленном решении 3, которое вы опубликовали, вы проигнорировали все советы о SQL - инъекции и все еще пытаетесь увеличить максимальный идентификатор в таблице-этот метод просто не работает.

Чтобы преодолеть вашу проблему SQL-инъекции (и случайно исправить любые проблемы, которые могут возникнуть у вас с типами столбцов и неправильно отформатированной конкатенацией строк), сделайте что-то вроде этого

String my_querry = "INSERT INTO product(reference,sn,cod_client,client,qtd,number)VALUES(@ref,@sn,@cod_client,@client,@qtd,@number)";
OleDbCommand cmd = new OleDbCommand(my_querry, con);
cmd.Parameters.AddWithValue("@ref", reference);
cmd.Parameters.AddWithValue("@sn", sn);
cmd.Parameters.AddWithValue("@cod_client", cod_client);
cmd.Parameters.AddWithValue("@client", client);
cmd.Parameters.AddWithValue("@qtd", qtd);
cmd.Parameters.AddWithValue("@number", number);
cmd.ExecuteNonQuery();
Чтобы получить последний введенный идентификатор, сделайте это
cmd.CommandText = "Select @@Identity";
int newID = (int)cmd.ExecuteScalar();
Примечание: это то же самое cmd объект, который использовался для выполнения команды Insert.
Не закрывайте соединение перед использованием Select @@Identity
Не выполняйте никаких других команд SQL на этом соединении перед использованием Select @@Identity


Рейтинг:
0

Member 12801143

Хорошо, я попробовал это и работает, но как я теперь делаю, чтобы увеличить это значение +1?

OleDbConnection con = new OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=Aneis_Calibre.accdb");
        con.Open();
        OleDbDataReader myReader = null;
        OleDbCommand number = new OleDbCommand("SELECT TOP 1 [number] FROM product Order by [number] desc", con);
        myReader = number.ExecuteReader();
        while (myReader.Read())
        {

            textBox_num.Text = (myReader["number"].ToString());

        }
        con.Close();


CHill60

Это не решение проблемы. Вы должны использовать зеленую ссылку улучшить вопрос в своем посте, чтобы добавить дополнительную информацию, или использовать "Есть вопрос или комментарий?" ссылка рядом с сообщением, чтобы ответить на конкретное решение.
Как уже указывалось, вы не должны увеличивать это число - используйте поле Autonumber в базе данных