【问题标题】:Specified cast is not valid when trying Convert.ToInt32(value)尝试 Convert.ToInt32(value) 时指定的转换无效
【发布时间】:2012-10-22 14:28:19
【问题描述】:

我正在尝试运行一个存储过程,但由于某种原因它一直告诉我"Specified cast is not valid"。 “hidSelectedExpenseIDs”是一个隐藏字段,填充了一个 id 的 javascript 数组。

示例:"hidSelectedExpenseIDs.Value" 看起来像“123,124,125,126”。这就是为什么我在里面有.Split(',')

这是我的代码:

public void hasExhistingExpenseInvoice()
{
    string[] Expenses = hidSelectedExpenseIDs.Value.Split(',');

    //check if there is an existing invoice. Then report back to the user so the
    //user knows if he/she has to check overwrite option.
    bool invoiceExists = false;

    foreach (var expense in Expenses)
    {
        var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["OSCIDConnectionString"].ToString());
        var command = new SqlCommand("p_CaseFiles_Expenses_InvoiceExhists", connection);
        command.Parameters.Add(new SqlParameter("@ExpenseID", SqlDbType.Int));
        command.Parameters["@ExpenseID"].Value = Convert.ToInt32(expense);
        command.CommandType = CommandType.StoredProcedure;
        try
        {
            connection.Open();
            invoiceExists = (bool)command.ExecuteScalar();
            if (invoiceExists)
            {
                //previous invoice exhists
                Warning1.Visible = true;
                Warning1.Text = "There is an exhisting Invoice.";
            }
        }
        catch (SqlException sql)
        {
            lblStatus.Text = "Couldn't connect to the Database - Error";
            lblStatus.ForeColor = System.Drawing.Color.Red;
        }
        catch (Exception ex)//catches exception here
        {
            lblStatus.Text = "An error occured";
            lblStatus.ForeColor = System.Drawing.Color.Red;
        }
        finally
        {
            if (connection.State == ConnectionState.Open)
                connection.Close();
        }
    }
}

这是我的存储过程:

ALTER PROCEDURE dbo.[InvoiceExhists]
@ExpenseID int
AS
BEGIN
    SELECT InvNumber FROM dbo.Expenses from ExpID = @ExpenseID
END

【问题讨论】:

  • 听起来像hidSelectedExpenseIDs 并不总是包含您认为它包含的内容。失败时它的价值是什么?
  • 使用断点进行调试,看看变量费用的值是多少
  • 您确定您的hidSelectedExpenseIDs.Value 末尾没有“,”吗?
  • 当我通过调试器运行它时,值是“295”作为字符串因此转换。它只是让我有点困惑,因为我让它在我的代码的其他部分做同样的事情并且它有效。它必须是 (bool)cmd.ExecuteScalar() 之类的 ramhound 建议
  • 提示 1: 不要在循环语句中创建连接。您正在为每次迭代打开一个连接。 提示 2: 使用 using 语句来处理连接和命令对象。

标签: c# sql-server tsql stored-procedures exception-handling


【解决方案1】:

逻辑错误。

您的查询返回一个数字,而您正试图将其直接转换为布尔值,这在 C# 中无法完成。

某些语言会将任何非零值解释为 true,但 C# 并非如此,它会抛出异常。

您需要比较返回的值。

在这种情况下,您应该只检查是否有值,因为如果发票不存在,则会返回 NULL。

这看起来像这样:

invoiceExists = command.ExecuteScalar() != null ;

我还建议阅读此thread 并考虑使用 UDF 而不是标量存储过程。

【讨论】:

  • 感谢您提供此信息。我从来不知道你可以做 ExecuteScalar() != null;
  • 这将评估并返回一个布尔值,然后将其分配给您的 invoiceExists 变量。
【解决方案2】:

更改您的存储过程。这符合您的要求

ALTER PROCEDURE [dbo].[InvoiceExhists]
@ExpenseID int
AS
BEGIN
if exists(select * Expenses where ExpID = @ExpenseID)
select 1
else
select 0
END

【讨论】:

  • 由于某种原因,即使没有结果,这段代码仍然返回 1
  • @john 您是否将缺少的“来自”添加到选择中
【解决方案3】:

该异常可能是由invoiceExists = (bool)command.ExecuteScalar(); 引起的,考虑到它是在 try 语句中发生的唯一转换。你需要查看ExecuteScalar()的返回结果来解决你的问题。

【讨论】:

  • 当我在我的数据库中运行查询时,它返回“InvNumber”作为标题,然后返回“12345”,所以它返回一个值
  • @john - 这些都不能转换为布尔值。事实上它们都是字符串值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-25
  • 2012-01-15
  • 1970-01-01
  • 1970-01-01
  • 2011-08-30
  • 1970-01-01
相关资源
最近更新 更多