【问题标题】:Failed to convert parameter value from a String to a Int32无法将参数值从 String 转换为 Int32
【发布时间】:2013-02-01 19:33:07
【问题描述】:

我正在使用 MVC3 和 SQL 2005。我收到错误消息:“将数据类型 varchar 转换为数字时出错。”我相信这是因为我为 QTYORDER 使用“1”而不是“1.00000”而生成的。对 QTYORDER 使用“1.00000”我现在看到错误:“无法将参数值从字符串转换为 Int32。”

我尝试使用 Convert.ToInt32(Variable),如下所示:

cmd.Parameters.Add("@QTYSOLD", SqlDbType.Int).Value = Convert.ToInt32(QTYORDER);

返回:“输入字符串的格式不正确。” Int.Parse(QTYORDER) 做同样的事情......

SQL 存储过程变量:

Procedure [dbo].[SVC_AddPart_To_Service_Call]      
    (@SRVRECTYPE smallint,
     @CALLNBR char(11),
     @TECHID char(11),
     @LINITMTYP char(3),
     @ITEMNMBR char(31),
     @QTY numeric(19,5) = 0,
     @QTYSOLD numeric(19,5) = 0,
     @STARTDATE datetime = '01/01/1900 00:00:00',   
     @STARTTIME datetime = '01/01/1900 00:00:00',
     @ENDDATE datetime = '01/01/1900 00:00:00',
     @ENDTIME datetime = '01/01/1900 00:00:00',
     @Status int output) As ...

MVC C# 代码:

SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["CPLU"].ConnectionString);
var cmd = new SqlCommand("SVC_AddPart_To_Service_Call", conn);
cmd.CommandType = CommandType.StoredProcedure;

cmd.Parameters.Add("@SRVRECTYPE", SqlDbType.SmallInt).Value = "2";
cmd.Parameters.Add("@CALLNBR", SqlDbType.Char).Value = CALLNBR;
cmd.Parameters.Add("@TECHID", SqlDbType.Char).Value = Session["TechID"];
cmd.Parameters.Add("@LINITMTYP", SqlDbType.Char).Value = "P";
cmd.Parameters.Add("@ITEMNMBR", SqlDbType.Char).Value = ITEMNMBR;
cmd.Parameters.Add("@QTY", SqlDbType.Int).Value = QTYORDER;
cmd.Parameters.Add("@QTYSOLD", SqlDbType.Int).Value = QTYORDER;
cmd.Parameters.Add("@STARTDATE", SqlDbType.DateTime).Value = "1900-01-01 00:00:00.000";
cmd.Parameters.Add("@STARTTIME", SqlDbType.DateTime).Value = "1900-01-01 00:00:00.000";
cmd.Parameters.Add("@ENDDATE", SqlDbType.DateTime).Value = "1900-01-01 00:00:00.000";
cmd.Parameters.Add("@ENDTIME", SqlDbType.DateTime).Value = "1900-01-01 00:00:00.000";
cmd.Parameters.Add("@STATUS", SqlDbType.Int);
cmd.Parameters["@STATUS"].Direction = ParameterDirection.Output;

conn.Open();
cmd.ExecuteNonQuery();
conn.Close();

MVC 剃刀代码:

@using (Html.BeginForm()) 
{
    @Html.ValidationSummary(true)
    <fieldset>

            @Html.LabelFor(model => model.CALLNBR, "Call Number")
            @Html.Label("CALLNBR", (string)ViewBag.CALLNBR)
            @Html.ValidationMessageFor(model => model.ITEMDESC)
        <br />
            @Html.LabelFor(model => model.ITEMNMBR, "Item Number")
            @Html.DropDownList("ITEMNMBR", (SelectList) ViewBag.Items, "Please Select a Part #")
            @Html.ValidationMessageFor(model => model.ITEMNMBR)
        <br />
            @Html.LabelFor(model => model.ITEMDESC, "Description")
            @Html.EditorFor(model => model.ITEMDESC)
            @Html.ValidationMessageFor(model => model.ITEMDESC)
        <br />
            @Html.LabelFor(model => model.QTYORDER, "Quantity")
            @Html.EditorFor(model => model.QTYORDER, new { required = "required"})
            @Html.ValidationMessageFor(model => model.QTYORDER)
        <br />
            <input type="submit" class="submit" value="Add Part" />

    </fieldset>
}

我试图通过表单传递的值:

CALLNBR = 0000198210 
ITEMNMBR = RF5-1885 (22 trailing spaces)
QTYORDER = 1

取自 SQL 表中一行的值:

CALLNBR = 0000198638  
ITEMNMBR = RM1-0043 (22 trailing spaces)
QTYORDER = 1.00000

问题:

1) 由于 SP 具有为 STARTDATE、STARTTIME、ENDDATE 和 ENDTIME 编码的默认值...在 MVC 应用程序上添加参数时是否需要提供这些值?

2) 我将如何在此处使用 Try-Catch,这会给我一个更好的错误消息吗?我真的可以跟进吗?

3) 有没有办法在 C# 中将 QTYORDER 值转换为小数点后 5 位?这将确保它以 #.00000 格式提交...

注意事项:

我正在使用实体框架,但我无法将存储过程映射到该表的选择插入函数,因为该 SP 用于添加零件,而另一个 SP 用于添加人工。

【问题讨论】:

    标签: c# sql asp.net-mvc-3 stored-procedures


    【解决方案1】:

    要回答您的几个问题,您不需要将可选参数传递给存储过程——它们将使用它们的默认值。

    关于 try-catch,只需在线快速搜索并使用您的断点——我会将它放在您上面提供的整个代码块周围。应该能够更好地了解引发的异常。

    需要考虑的其他几个 cmets:

    不要尝试 int.parse,而是使用 int.TryParse:

    int orderQty = 0;
    int.TryParse(QTYORDER, out orderQty);
    if (orderQty == 0)
        //You potentially have a problem with binding 
    

    另外,您的代码将 QTYORDER 作为整数传递,但存储过程接受小数。改变这个:

    cmd.Parameters.Add("@QTY", SqlDbType.Int).Value = QTYORDER;
    

    cmd.Parameters.Add("@QTY", SqlDbType.Decimal).Value = QTYORDER;
    

    【讨论】:

    • 抱歉耽搁了。好久没有机会重新戴上这顶帽子了。将 QTYORDER 的 sqldbtype 从 int 更改为 decimal。现在我得到一个新的转换错误......耶! “将数据类型 varchar 转换为数值时出错。”
    • 那是从哪一行来的? QTYORDER 的价值是多少?使用 Decimal.TryParse 而不是 int.TryParse 来转换它。祝你好运。
    • 看起来我需要 sql 类型 (int) 用于 callnbr 和 techid,需要 sql 类型 (char) 用于 linitmtyp 和 itemnmbr,以及 sql 类型 (decimal) 用于 qty 和 qtysold。现在我又遇到了另一个错误...“没有类型为 'IEnumerable' 的 ViewData 项具有键 'ITEMNMBR'。”由于此错误似乎不是转换问题,因此我将关闭此问题,在我自己尝试解决此错误后,我将创建一个新问题。
    • 你帮了很多忙。我需要十进制...之后它只是找出我需要的其他...解决的错误越多,我似乎生成的越多...哦,谢谢!
    【解决方案2】:

    您确定 QTYORDER 不为空吗? MVC 可能在这里丢失了模型绑定。快速检查一下它是否为空

    在你添加参数之前把它放在 bool x 行上添加一个断点,看看它是否命中。如果为null,则模型绑定有问题,请检查您的模型代码

    if(QTYORDER == null){
    
         bool x = true;
    
    }
    

    尝试修剪字符串以确保没有空格?

    Convert.ToInt32(QTYORDER.Trim());
    

    如果您想将其转换为小数点后 5 位

    Math.Round(Convert.ToDecimal(QTYORDER.Trim()), 5);
    

    【讨论】:

      猜你喜欢
      • 2015-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多