Не удалось преобразовать символ в числовое значение

Я сталкиваюсь со следующим исключением, когда пытаюсь использовать параметризованный запрос с informix .

A character to numeric conversion process failed

                    StringBuilder sQuery = new StringBuilder();
                    Dictionary<string, string> paramList = new Dictionary<string, string>();
                    cmdTxt.Append(" UPDATE userwidgetto SET widget_color = ?, widget_column = ?, widget_order = ?,widget_state = ?,widget_type = ? ");
                    cmdTxt.Append(" WHERE process_id = ? AND emp_num = ? ");

                    paramList.Add("process_id", Process_id.ToString());
                    paramList.Add("emp_num", Emp_num.ToString());
                    paramList.Add("widget_color", Widget_color.TrimEnd());
                    paramList.Add("widget_column", Widget_column.ToString().TrimEnd());
                    paramList.Add("widget_order", Widget_order.ToString());
                    paramList.Add("widget_state", Widget_state.ToString());
                    paramList.Add("widget_type", Widget_type.ToString());
                    affectedRow = DAL_Helper.Execute_NonQuery(cmdTxt.ToString(), CommandType.Text, paramList);

public int Execute_NonQuery(string cmdText, CommandType cmdType, Dictionary<string, string> Param_arr)
            {
                Open_Connection();
                int return_val = -1;
                command.CommandText = cmdText;
                command.CommandType = cmdType;
                command.Transaction = current_trans;
                command.Parameters.Clear();
                if (Param_arr != null)
                {
                    foreach (KeyValuePair<string, string> parameter in Param_arr)
                    {
                        param = command.CreateParameter();
                        param.ParameterName = parameter.Key.ToString();
                        if (parameter.Value.ToString() == "Null" || string.IsNullOrEmpty(parameter.Value))
                            param.Value = DBNull.Value;
                        else
                            param.Value = parameter.Value.ToString();
                        command.Parameters.Add(param);
                    }
                }
                try
                {
                    return_val = command.ExecuteNonQuery();//means no error message //OK                
                }
                catch (IfxException ifxEx)// Handle IBM.data.informix : mostly catched
                {
                    return_val = ifxEx.Errors[0].NativeError;
                }
                catch (Exception Ex)
                {
                    ErrMapping.WriteLog("\r\n" + Ex.Message);
                    return_val = ExCodeConst;
                }
                finally
                {
                    Close_Connection();
                }
                return return_val;
            }

person Anyname Donotcare    schedule 14.06.2012    source источник


Ответы (1)


Я полагаю, вы используете клиент OleDb. В этом случае параметры должны быть вставлены в том же порядке, что и заполнители командной строки (?).

cmdTxt.Append(" UPDATE userwidgetto SET widget_color = ?, widget_column = ?, widget_order = ?,widget_state = ?,widget_type = ? ");
cmdTxt.Append(" WHERE process_id = ? AND emp_num = ? ");
paramList.Add("widget_color", Widget_color.TrimEnd());
paramList.Add("widget_column", Widget_column.ToString().TrimEnd());
paramList.Add("widget_order", Widget_order.ToString());
paramList.Add("widget_state", Widget_state.ToString());
paramList.Add("widget_type", Widget_type.ToString()); 
paramList.Add("process_id", Process_id.ToString());
paramList.Add("emp_num", Emp_num.ToString());
affectedRow = DAL_Helper.Execute_NonQuery(cmdTxt.ToString(), CommandType.Text, paramList); 

Кроме того, Dictionary‹string, string› paramList заставляет каждое значение, передаваемое DAL_Helper, быть строкового типа.
И, я думаю, это не так, судя по именам параметров (process_id не строка в таблице базы данных, верно?).
Как уже было предложено в комментарии, вы должны изменить paramList на Dictionary‹string, object›, а затем добавить параметры с преобразованием строки только там, где это уместно (это означает, что тип данных столбца таблицы является строковым типом).

person Steve    schedule 14.06.2012
comment
Отлично, это решило мою проблему .. действительно спасибо, но я не понимаю последний комментарий, у меня уже есть словарь, как разрешить принимать все типы данных без необходимости конвертировать tostring() - person Anyname Donotcare; 14.06.2012
comment
Не могли бы вы привести простой пример, пожалуйста? - person Anyname Donotcare; 14.06.2012
comment
Если вы объявите Dictionary<string, object> paramList, вы можете написать paramList.Add("process_id", Process_id);. Ваш класс DAL_Helper при добавлении этого параметра в OleDbParameterCollection для обновления вашей таблицы увидит, что у вас есть объект целочисленного типа, и передаст целое число команде, которая обновит вашу таблицу. - person Steve; 14.06.2012
comment
Было бы очень полезно, если бы вы также могли показать код DAL_Helper.ExecuteNonQuery. - person Steve; 14.06.2012
comment
Действительно странно, каждый параметр преобразуется в строку. Я не знаю Informix, и драйвер OleDb раньше работал с серверной частью базы данных, но я думаю, что у вас здесь большие проблемы. У вас есть только строковые столбцы в ваших таблицах? (Просто говорю, чтобы очистить вещи, это будет огромной ошибкой) - person Steve; 14.06.2012
comment
:) у меня есть все типы, но мы используем этот слой давно, не могли бы вы дать предложения по улучшению этого метода? - person Anyname Donotcare; 14.06.2012