Процедура C # и MySql - PullRequest
       8

Процедура C # и MySql

0 голосов
/ 10 сентября 2018

У меня есть 2 таблицы. Main_items и Help_items.

Main_items содержит эти столбцы
(Main_items_id, main_items_name)

Help_items содержит эти столбцы
(help_items_id, Help_items_name, main_items_id).

Я написал эту процедуру

CREATE DEFINER=`root`@`localhost` PROCEDURE `thamer1`(in main_items_id_ int, 
out res int)
BEGIN
declare a int;
declare b int;

select count(help_items_id)
into a from help_items
where main_items_id=main_items_id_;

if a=0 then
    set b=(main_items_id_*10)+1;
    set res=b;
else
    select COALESCE(max(help_items_id),0)+1
    into res
    from help_items
    where main_items_id=main_items_id_;
end if;
END

Эта процедура работает с MySql WrokBench.

И это для кода C #

private void a_KeyDown(object sender, KeyEventArgs e)
    {
        using (MySqlConnection mysqlcon6 = new 
MySqlConnection(connectString))
        {
            mysqlcon6.Open();
            MySqlCommand mysqlcmd6 = new MySqlCommand("thamer1", mysqlcon6);

            mysqlcmd6.CommandType = CommandType.StoredProcedure;
            mysqlcmd6.CommandText = "thamer1";
            mysqlcmd6.Parameters.Add("@main_items_id_", MySqlDbType.Int32).Value = a.Text;
            mysqlcmd6.Parameters.Add("@res", MySqlDbType.Int32).Value=HITEM.Text;
            mysqlcmd6.ExecuteNonQuery();
           // MessageBox.Show("saved");
            // GridFill();
        }
    }

Я выбираю значение (для main_items_id) из DataGrideView и извлекаю его в текстовое поле с именем a.

Когда я нажимаю ENTER, я получаю это сообщение

System.FormatException: 'Входная строка была в неправильном формате'

Я надеюсь помочь мне решить эту ошибку.

Ответы [ 2 ]

0 голосов
/ 10 сентября 2018

Удалите часть этой строки, которая устанавливает значение параметра:

mysqlcmd6.Parameters.Add("@res", MySqlDbType.Int32).Value=HITEM.Text;

Похоже, вы ожидаете, что вы привязаете результат @res к текстовому полю HITEM, а это не то, что происходит,HITEM.Text - это просто строка, и когда вы присваиваете это значение параметру int, вы говорите MySql, что ожидаете, что он сможет проанализировать эту строку в int.

Вместо этого создайте только параметр, например:

mysqlcmd6.Parameters.Add("@res", MySqlDbType.Int32);

Вам также нужно сообщить ADO.Net, что это параметр OUTPUT.Затем проверьте значение параметра после того, как запрос выполняется, назначив значение параметра для HITEM.Text, а не из HITEM.Text:

private void a_KeyDown(object sender, KeyEventArgs e)
{
    //You can re-use the *names* of these variables, since their scopes are limited to the method
    //You can also stack them to share the same scope block and reduce nesting/indentation
    using (var con = new MySqlConnection(connectString))
    using (var cmd = new MySqlCommand("thamer1", con))
    {
        cmd.CommandType = CommandType.StoredProcedure;
        //  mysqlcmd6.CommandText = "thamer1"; //you already did this in constructor. Don't need to do it again
        cmd.Parameters.Add("@main_items_id_", MySqlDbType.Int32).Value = a.Text;
        //DON'T assign to the Value, but DO make sure ADO.Net understands this is an OUTPUT parameter
        cmd.Parameters.Add("@res", MySqlDbType.Int32).Direction = ParameterDirection.Output;

        //wait as long as possible to call Open()
        con.Open();
        cmd.ExecuteNonQuery();

        //Now you can assign **to** HITEM.Text, rather than from it.
        HITEM.Text = cmd.Parameters["@res"].Value;
    }
    //End the scope as soon as possible, so the connection can be disposed faster
    // MessageBox.Show("saved");
    // GridFill();
}

И вот оноопять же без лишних комментариев:

private void a_KeyDown(object sender, KeyEventArgs e)
{
    using (var con = new MySqlConnection(connectString))
    using (var cmd = new MySqlCommand("thamer1", con))
    {
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.Add("@main_items_id_", MySqlDbType.Int32).Value = a.Text;
        cmd.Parameters.Add("@res", MySqlDbType.Int32).Direction = ParameterDirection.Output;

        con.Open();
        cmd.ExecuteNonQuery();
        HITEM.Text = cmd.Parameters["@res"].Value;
    }
}

Еще более эффективная практика - переместить все ваши методы SQL в отдельный класс, от ваших обработчиков событий.Обработчики событий должны вызывать только методы в новом классе, например:

public static class DB
{
    private static string connectionString = "...";

    public static int thamer(int main_item_id)
    {
        using (var con = new MySqlConnection(connectString))
        using (var cmd = new MySqlCommand("thamer1", con))
        {
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.Add("@main_items_id_", MySqlDbType.Int32).Value = main_item_id;
            cmd.Parameters.Add("@res", MySqlDbType.Int32).Direction = ParameterDirection.Output;

            con.Open();
            cmd.ExecuteNonQuery();
            return (int)cmd.Parameters["@res"].Value;
        }
    }
}

private void a_KeyDown(object sender, KeyEventArgs e)
{
    HITEM.Text = DB.thamer(int.Parse(a.Text)).ToString();
}
0 голосов
/ 10 сентября 2018

Изменить это

 mysqlcmd6.Parameters.Add("@main_items_id_", 
MySqlDbType.Int32).Value = a.Text;
            mysqlcmd6.Parameters.Add("@res", MySqlDbType.Int32).Value = 
HITEM.Text;

до

int value1 = 0;
int value2 = 0;

if (!Int32.Text.TryParse(a.Text) || !Int32.TryParse(HITEM.Text))
{
    return;
}
 mysqlcmd6.Parameters.Add("@main_items_id_",  MySqlDbType.Int32).Value =  value1;
 mysqlcmd6.Parameters.Add("@res", MySqlDbType.Int32).Value = value2;
...