Lerroy Fernandes Ответов: 3

C# нужна помощь кода для написания кода для подключения формы к SQL


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

Я написал следующий код
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Data.SqlClient;

namespace WindowsFormsApp2
{
    public partial class Form1 : Form
    {
        SqlConnection con=new SqlConnection(@"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\lerro\OneDrive\Documents\DatabaseAmal.mdf;Integrated Security=True;Connect Timeout=30");

        public SqlConnection Con { get => con; set => con = value; }

        public Form1()
        {
            InitializeComponent();
        }

        private void label1_Click(object sender, EventArgs e)
        {

        }

        private void label2_Click(object sender, EventArgs e)
        {

        }

        private void label5_Click(object sender, EventArgs e)
        {

        }

        private void label9_Click(object sender, EventArgs e)
        {

        }

        private void button4_Click(object sender, EventArgs e)
        {
            con.Open();
            SqlCommand cmd = con.CreateCommand();
            cmd.CommandType = CommandType.Text;
            cmd.CommandText = "insert into Amal values ('" + this.textBox1.Text + "','" + this.textBox5.Text + "','" + this.textBox2.Text + "','" + this.textBox3.Text + "','" + this.textBox4.Text + "','" + this.textBox6.Text + "','" + this.textBox4.Text + "','" + this.textBox7.Text + "','" + this.comboBox1.Text + "','" + this.textBox8.Text + "','" + this.textBox9.Text + "','" + this.dateTimePicker2.Text + "','" + this.textBox10.Text + "','" + this.comboBox2.Text + "','" + this.comboBox3.Text + "','" + this.comboBox4.Text + "','" + this.textBox14.Text + "','" + this.textBox11.Text + "','" + this.textBox12.Text + "','" + this.textBox13.Text + "','" + this.BrowseTextbox.Text + "','" + this.pictureBox1.Text + "','" + this.textBox15.Text + "','" + this.dateTimePicker1.Text + "');";
            cmd.ExecuteNonQuery();
            con.Close();

            MessageBox.Show("record inserted successfully");

        }

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog open = new OpenFileDialog();
            open.Filter = "Image Files(*jpg; *.jpeg; *.gif; *.bmp;)|*jpg; *.jpeg; *.gif; *.bmp;";
            if (open.ShowDialog() == DialogResult.OK)
            {
                BrowseTextbox.Text = open.FileName;
                pictureBox1.Image = new Bitmap(open.FileName);

            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            textBox1.Text = String.Empty;
            textBox2.Text = String.Empty;
            textBox3.Text = String.Empty;
            textBox4.Text = String.Empty;
            textBox5.Text = String.Empty;
            textBox6.Text = String.Empty;
            textBox7.Text = String.Empty;
            textBox8.Text = String.Empty;
            textBox9.Text = String.Empty;
            textBox10.Text = String.Empty;
            textBox11.Text = String.Empty;
            textBox12.Text = String.Empty;
            textBox13.Text = String.Empty;
            textBox14.Text = String.Empty;
            textBox15.Text = String.Empty;
            pictureBox1.Image = null;
            comboBox1.Text = String.Empty;
            comboBox2.Text = String.Empty;
            comboBox3.Text = String.Empty;
            comboBox4.Text = String.Empty;
            BrowseTextbox.Text = String.Empty;






        }

        private void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
        {
            
        }
    }
}


и я получаю следующую ошибку

Явное значение столбца identity в таблице 'Table' может быть задано только в том случае, если используется список столбцов и включен параметр IDENTITY_INSERT.'

Который в основном пытается вставить данные в столбец, который имеет автоматически сгенерированное значение. Запрос пытается добавить значение в этот столбец, что является проблемой.

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

Попробовал youtubing проблему и попытался кодировать, но что-то сломалось еще больше.
Нужно, чтобы кто-то помог мне исправить эту часть для меня. Пожалуйста !

3 Ответов

Рейтинг:
12

OriginalGriff

В таком маленьком фрагменте кода так много плохого ...
Самое главное, как уже упоминал Дэйв: никогда не объединяйте строки для построения 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;
Вполне допустимая команда "удалить таблицу"
--'
А все остальное-это комментарии.
Так оно и происходит: выбирает любые совпадающие строки, удаляет таблицу из базы данных и игнорирует все остальное.

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

Двигаясь вниз по приоритету, как сказал Джерри: всегда перечисляйте имена своих столбцов. Если вы этого не сделаете, то компонент database engine присваивает значения столбцам, начинающимся сверху, так что если у вас есть столбец идентификаторов, вставка автоматически завершится неудачей, как вы можете;t (в большинстве случаев) измените их, вот и вся идея.

Далее: ваше приложение рухнет, и ваш брат потеряет все данные, которые он ввел, если он сделает малейшую ошибку. Например, если он вводит буквенный символ в числовой столбец. И он это сделает, можете не сомневаться. Проверяйте свои данные, сообщайте о проблемах и не выполняйте никакой работы с базой данных, пока не убедитесь, что все данные верны.

После этого у нас есть "общие ошибки", которые также приведут к сбою вашего приложения, и снова он потеряет свои данные. Вместо того чтобы просто сообщать "это сработало", используйте try...catch блокируйте свой код и сообщайте о неудачах вместо того, чтобы просто "падать и умирать". Это простое изменение, которое означает гораздо меньше разочарований для вашего брата.

Двигаясь вперед, мы приходим к SQL - объектам, таким как соединения, команды, адаптеры данных - это дефицитные ресурсы, и их нужно очистить после использования, поэтому поместите конструкторы в using блоки, и пусть система убирает за вами!

Далее, чтобы быстро взглянуть на ваше жесткое кодирование строк подключения: это очень плохая идея, так как это означает, что вы должны менять свой код каждый раз, когда вы его выпускаете, и надеяться, что, черт возьми, вы все сделали правильно, потому что вы не можете протестировать строку для своей машины brothers на своей ... всегда используйте файл конфигурации или что-то подобное, чтобы вы могли получить его правильно один раз и никогда не изменять его, даже когда вы обновляете программное обеспечение.

И, наконец, вы используете имена. Прекратите использовать имена Visual Studio по умолчанию для всего - вы можете помнить, что "TextBox8" - это номер мобильного телефона сегодня, но когда вам придется изменить его через три недели, вы это сделаете? Используйте описательные имена - например, "tbMobileNo", - и ваш код станет легче читать, более самодокументируемым, легче поддерживать - и на удивление быстрее кодировать, потому что Intellisense может добраться до "tbMobile" за три нажатия клавиш, где "TextBox8" занимает размышление и 8 нажатий клавиш...

Сделайте это правильно, и ваш код станет чище, легче писать, легче читать, а также более надежным и удобным для пользователя.

int itemsCount;
if (!int.TryParse(tbNumberOfItems.Text, out itemsCount)
    {
    MessageBox.Show("Input Error", $"\"{tbNumberOfItems.Text}\" is not a valid number");
    return;
    }
try
    {
    using (SqlConnection con = new SqlConnection(strConnect))
        {
        con.Open();
        using (SqlCommand cmd = new SqlCommand("INSERT INTO myTable (Description, ItemsCount) VALUES (@DESC, @ITEMS)", con))
            {
            cmd.Parameters.AddWithValue("@DESC", description);
            cmd.Parameters.AddWithValue("@ITEMS", itemsCount);
            cmd.ExecuteNonQuery();
            }
        }
    }
catch (Exception ex)
    {
    MessageBox.Show("Insert failed", ex.Message);
    }


Рейтинг:
1

Gerry Schmitz

Вы не указали никаких имен столбцов в своей "вставке".

Вы создали столбец идентификаторов в своей базе данных, который "автоматически генерирует" первичные ключи.

Ваша вставка пытается обновить этот столбец, что недопустимо, если только IDENTITY_INSERT не включен.

Вам нужно прочитать больше о том, почему и когда столбцы идентификаторов (и то же самое для вставок с именами столбцов или без них)


Рейтинг:
1

Dave Kreskowiak

Это просто мерзость:

cmd.CommandText = "insert into Amal values ('" + this.textBox1.Text + "','" + this.textBox5.Text + "','" + this.textBox2.Text + "','" + this.textBox3.Text + "','" + this.textBox4.Text + "','" + this.textBox6.Text + "','" + this.textBox4.Text + "','" + this.textBox7.Text + "','" + this.comboBox1.Text + "','" + this.textBox8.Text + "','" + this.textBox9.Text + "','" + this.dateTimePicker2.Text + "','" + this.textBox10.Text + "','" + this.comboBox2.Text + "','" + this.comboBox3.Text + "','" + this.comboBox4.Text + "','" + this.textBox14.Text + "','" + this.textBox11.Text + "','" + this.textBox12.Text + "','" + this.textBox13.Text + "','" + this.BrowseTextbox.Text + "','" + this.pictureBox1.Text + "','" + this.textBox15.Text + "','" + this.dateTimePicker1.Text + "');";

Серьезно. Google для "параметризованных запросов C# sql", чтобы исправить этот беспорядок.

Почему это плохо? Google для "атаки SQL-инъекций".