Member 13362025 Ответов: 2

Ошибка преобразования типа данных varchar в числовой.


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

Я дал ссылку на изображение ошибки здесь :
Изображение здесь[^]


Сообщение об ошибке:
SqlException был необработан
Ошибка преобразования типа данных varchar в числовой.

private void balance_enery_Load(object sender, EventArgs e)
{
    label3.Visible = false;
    //SqlConnection con = new SqlConnection("data source=CLIENT-07\\SQLEXPRESS;integrated security=true;initial catalog=ATM;");
    con.Open();
    SqlCommand cmd = new SqlCommand("select  * from transactions where account_no='" + label3.Text + "'", con);
    SqlDataReader rdr= cmd.ExecuteReader();
    if (rdr.Read()) // Error is thrown on this line
    {
        label2.Text = rdr["total"].ToString();
    }
    rdr.Close();
    rdr.Dispose();
    con.Close();
}


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

Я попытался присоединиться .ToString() в строке, но все равно показывает ошибку

Richard Deeming

Вместо того чтобы размещать ссылку на изображение сообщения об ошибке, к которому многие люди не смогут получить доступ, просто разместите фактическое сообщение об ошибке. Во всплывающем окне ошибка в Visual Studio появится кнопка для копирования сведений об исключении в буфер обмена; нажмите ее и вставьте ошибку в свой вопрос.

2 Ответов

Рейтинг:
2

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

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

Предполагая, что номер вашего счета является числовым, вы должны использовать инт.Метод tryparse[^] чтобы преобразовать его в число - сообщая о любых проблемах пользователю вместо продолжения - и передать преобразованное значение в качестве параметра:
using (SqlConnection con = new SqlConnection(strConnect))
    {
    con.Open();
    using (SqlCommand cmd = new SqlCommand("SELECT Description FROM myTable WHERE ID = @ID", con))
        {
        using (SqlDataReader reader = cmd.ExecuteReader())
            {
            cmd.Parameters.AddWithValue("@ID", accountNo);
            if (reader.Read())
                {
                string desc = (string) reader["description"];
                Console.WriteLine("ID: {0}\n    {1}", accountNo, desc);
                }
            }
        }
    }


Рейтинг:
2

MadMyche

Originalgriff's ответ прямо на SQL-инъекцию; я не собираюсь перефразировать его.

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

То, что я собираюсь сделать, это предоставить вам основы того, как я буду кодировать этот метод в надежде, что он может помочь, с моими заметками о реализации
1. я понятия не имею, почему ваше соединение закомментировано, поэтому я снова включил его.
2. Занятия по SQL были завернуты в через блоки, чтобы правильно распорядиться/освобождения ресурсов.
3. В блоке try был реализован, так что вы можете получить некоторую обратную связь (хотя бы для отладки).
4. Добавлены переменные и tryparse сделал дешевые валидатор.
5. SQL-оператор был сокращен до одного и единственного элемента, который вы просите.
6. ExecuteScalar() был использован метод, поскольку существует только одно значение. Меньше накладных расходов.
7. Отзыв добавил Если записей не найдено

label3.Visible = false;
int AccountNo = -1;
string OutputMessage = string.Empty;

try {
    if (int.TryParse(label3.Text, out AccountNo)) {
        using (SqlConnection con = new SqlConnection("data source=CLIENT-07\\SQLEXPRESS;integrated security=true;initial catalog=ATM;")) {
            con.Open();
            using (SqlCommand cmd = new SqlCommand("SELECT total FROM transactions WHERE account_no=@AccountNo", con)) {
                cmd.Parameters.AddWithValue("@AccountNo", AccountNo);
                var SRV = cmd.ExecuteScalar();
                if (!SRV == null) {
                    OutputMessage = SRV.ToString();
                }
                else {
                    Output = "No Results Found";
                }
            }
        }
    }
    else {
        OutputMessage = "Label 3 was not a valid";
    }
    label2.Text = OutputMessage;
}
catch (Exception ex) { label2.Text = ex.Message; }