System.Data.SqlClient.SqlException: "Ошибка при преобразовании типа данных varchar к float."

Рейтинг: -3Ответов: 1Опубликовано: 13.08.2023

Не могу понять как исправить исключение System.Data.SqlClient.SqlException: "Ошибка при преобразовании типа данных varchar к float."

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.Data.SqlClient;


namespace Testdatabase
{
    enum RowState 
    {
        Existed,
        New,
        Modified,
        ModifiedNew,
        Deleted,
    }

    public partial class Form1 : Form
    {
        database dataBase = new database();
        int selectedRow;
        public Form1()
        {
            InitializeComponent();
            StartPosition = FormStartPosition.CenterScreen;
        }
        private void CreateColumns()
        {
            dataGridView1.Columns.Add("id", "ID");
            dataGridView1.Columns.Add("name_of", "ФИО студента");
            dataGridView1.Columns.Add("nomer_of", "Номер группы");
            dataGridView1.Columns.Add("average_of", "Средний балл");
            dataGridView1.Columns.Add("IsNew", String.Empty);
        }
        private void ClearFields()
        {
            textBox_id.Text = "";
            textBox_name.Text = "";
            textBox_nomer.Text = "";
            textBox_average.Text = "";
        }
        private void ReadSingleRow(DataGridView dgw, IDataRecord record)

        {
            dgw.Rows.Add(record.GetInt32(0), record.GetString(1), record.GetInt32(2), record.GetDouble(3), RowState.ModifiedNew);
        }

        private void RefreshDataGridView(DataGridView dgw)
        {
            dgw.Rows.Clear();
            String queryString = $"select*from test_db";
            SqlCommand command = new SqlCommand(queryString, dataBase.getConnection());
            dataBase.openConnection();
            SqlDataReader reader = command.ExecuteReader();
            while(reader.Read())
            {
                ReadSingleRow(dgw, reader);
            }
            reader.Close();
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            CreateColumns();
            RefreshDataGridView(dataGridView1);
        }

        private void label1_Click(object sender, EventArgs e)
        {

        }

        private void button2_Click(object sender, EventArgs e)
        {
            deleteRow();
            ClearFields();
        }

        private void Control_info_Click(object sender, EventArgs e)
        {
            ClearFields();
        }

        private void pictureBox1_Click(object sender, EventArgs e)
        {

        }

        private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            selectedRow = e.RowIndex;
            if(e.RowIndex>=0)
            {
                DataGridViewRow row = dataGridView1.Rows[selectedRow];
                textBox_id.Text = row.Cells[0].Value.ToString();
                textBox_name.Text = row.Cells[1].Value.ToString();
                textBox_nomer.Text = row.Cells[2].Value.ToString();
                textBox_average.Text = row.Cells[3].Value.ToString();

            }
        }

        private void Search (DataGridView dgw)
        {
            dgw.Rows.Clear();
            string searchString = $"select * from test_db where concat(id, name_of,nomer_of,average_of)like'%" + textBox_Search.Text + "%'";
            SqlCommand com=new SqlCommand(searchString, dataBase.getConnection());
            dataBase.openConnection();
            SqlDataReader read = com.ExecuteReader();
            while (read.Read())
            {
                ReadSingleRow(dgw, read);

            }
            read.Close();

        }


        private void deleteRow()
        {
            int index = dataGridView1.CurrentCell.RowIndex;
            dataGridView1.Rows[index].Visible = false;
            if (dataGridView1.Rows[index].Cells[0].Value.ToString() == string.Empty)
            {
                dataGridView1.Rows[index].Cells[4].Value = RowState.Deleted;
                return;
            }
            dataGridView1.Rows[index].Cells[4].Value = RowState.Deleted;
        }
        private void Update()
        {
            dataBase.openConnection();
            for(int index=0;index<dataGridView1.RowCount;index++)
            {
                var rowState = (RowState)dataGridView1.Rows[index].Cells[4].Value;
                if (rowState == RowState.Existed)
                    continue;
                if (rowState==RowState.Deleted)
                {
                    var id = Convert.ToInt32(dataGridView1.Rows[index].Cells[0].Value);
                    var deleteQuery = $"delete from test_db where id={id}";
                    var command = new SqlCommand(deleteQuery,dataBase.getConnection());
                    command.ExecuteNonQuery();
                }     
                if (rowState==RowState.Modified)
                {
                    var id=dataGridView1.Rows[index].Cells[0].Value.ToString();
                    var name = dataGridView1.Rows[index].Cells[1].Value.ToString();
                    var nomer = dataGridView1.Rows[index].Cells[2].Value.ToString();
                    var average = dataGridView1.Rows[index].Cells[3].Value.ToString();

                    var changeQuery = $"update test_db set name_of='{name}',nomer_of='{nomer}',average_of='{average}' where id='{id}'";
                    var command = new SqlCommand(changeQuery, dataBase.getConnection());
                    command.ExecuteNonQuery();


                }
            } 
            dataBase.closeConnection();
        }
        private void pictureBox2_Click(object sender, EventArgs e)
        {
            RefreshDataGridView(dataGridView1);
            ClearFields();
        }

        private void New_Student_info_Click(object sender, EventArgs e)
        {
            Add_Form addfrm = new Add_Form();
            addfrm.Show();
        }

        private void Search_TextChanged(object sender, EventArgs e)
        {
            Search(dataGridView1);
        }

        private void Save_Click(object sender, EventArgs e)
        {
            Update();
        }
        private void Changer()
        {
            var SelectedRowIndex = dataGridView1.CurrentCell.RowIndex;
            var id = textBox_id.Text;
            var name = textBox_name.Text;
            var average = textBox_average.Text;
            int nomer;
            if (dataGridView1.Rows[SelectedRowIndex].Cells[0].Value.ToString()!=string.Empty)
            {
                if(int.TryParse(textBox_nomer.Text,out nomer))
                {
                    dataGridView1.Rows[SelectedRowIndex].SetValues(id, name, nomer, average);
                    dataGridView1.Rows[SelectedRowIndex].Cells[4].Value = RowState.Modified;
                }
                else
                {
                    MessageBox.Show("Убедитесь, что номер группы введён верно");
                }
                
            }

        }
        private void Change_Click(object sender, EventArgs e)
        {
            Changer();
            ClearFields();
        }
    }
}

исключение в 160 строке command.ExecuteNonQuery();

Ответы

▲ 0

Строки считать не будем, но если поискать по тексту программы command.ExecuteNonQuery();, то эта строка есть только в двух местах кода. В первом месте происходит удаление записи, при удалении такой ошибки быть на может. Посмотрим второй кусок кода:

var id=dataGridView1.Rows[index].Cells[0].Value.ToString();
var name = dataGridView1.Rows[index].Cells[1].Value.ToString();
var nomer = dataGridView1.Rows[index].Cells[2].Value.ToString();
var average = dataGridView1.Rows[index].Cells[3].Value.ToString();

var changeQuery = $"update test_db set name_of='{name}',nomer_of='{nomer}',average_of='{average}' where id='{id}'";
var command = new SqlCommand(changeQuery, dataBase.getConnection());
command.ExecuteNonQuery();

Все ваши переменные имеют тип "строка". Что же из использованных в вашем запросе UPDATE полей таблицы может быть на самом деле типа float? Скорее всего это average_of. При этом записали вы её в строку обновления данных с кавычками: average_of='{average}'. Для начала попробуйте убрать кавычки: average_of={average}. Но ещё более правильно будет наверное распарсить переменную average в тип float и уже в таком виде подставить её в строку обновления БД. А ещё более правильно всё-таки не пользоваться интерполяцией строк и ручным созданием строк обновления БД, а использовать подстановку параметров через command.Parameters.AddWithValue.

Если вы просто подставляете в SQL запрос всё, что вам ввёл пользователь в поле ввода, то ваша база рано или поздно может пасть жертвой SQL injection, лучше так никогда не делайте.