将nvarchar值转换为数据类型int时转换失败

时间:2015-11-02 09:03:03

标签: c# sql asp.net sql-server parameter-passing

我尝试执行以下查询但获得异常。

using (SqlConnection con = new SqlConnection(UserDatabase.getConnectionString()))
{
    using (SqlCommand cmd = new SqlCommand("SELECT * FROM Order_Header where Status IN (@Values)"))
    {
        using (SqlDataAdapter sda = new SqlDataAdapter())
        {
            try
            {
                        cmd.Connection = con;
                        con.Open();
                        sda.SelectCommand = cmd;

                        // This is for test purposes
                        List<int> yourValues = new List<int>() { 1, 2, 3, 4, 5 };

                        //Get values for IN
                        string x = String.Join(",", yourValues.Select(s => String.Format("'{0}'", s)).ToArray());

                        // Add parameter
                        cmd.Parameters.AddWithValue("@Values", x);


                        DataTable dt = new DataTable();

                        sda.Fill(dt);
                        order_details.SetDataSource(dt);
                        SalesReport.ReportSource = order_details;
            }
            catch (Exception ex)
            {
                 scriptMessage(ex.ToString);
            }
            finally
            {
                        con.Close();
                        sda.Dispose();
                        con.Dispose();
            }
        }
    }
}

执行此查询时,我收到以下异常:

  

转换nvarchar值&#39; 1&#39;&#39; 2&#39;&#39; 3&#39;,&#39; 4&#39;时转换失败, &#39; 5&#39;&#39;数据类型int。

为什么会这样?请帮忙

2 个答案:

答案 0 :(得分:0)

您的状态是varchar,您的列表是int。 如果它包含如下数据,你需要将状态转换为int: - 从(选择&#39; 1&#39;作为状态)x;

中选择强制转换(状态为int)

答案 1 :(得分:0)

更新

我已经改变了你的代码,现在工作正常:

方法1:

using (SqlConnection con =new SqlConnection(/*Your Connection String*/))
        {
            using (SqlCommand cmd = new SqlCommand())
            {
                using (SqlDataAdapter sda = new SqlDataAdapter())
                {
                    try
                    {
                        cmd.Connection = con;
                        con.Open();
                        sda.SelectCommand = cmd;

                        // This is for test purposes
                        List<int> yourValues = new List<int>() { 1, 2, 3, 4, 5 };

                        //Get values for IN
                        string x = string.Join(",", yourValues.Select(s => String.Format("{0}", s)).ToArray());

                        cmd.CommandText = "SELECT* FROM Order_Header where Status IN(" + x + ")";

                        DataTable dt = new DataTable();
                        sda.Fill(dt);
                    }
                    catch
                        (Exception
                            ex)
                    {
                        MessageBox.Show(ex.Message);
                    }
                    finally
                    {
                        con.Close();
                        sda.Dispose();
                        con.Dispose();
                    }
                }
            }

方法2:

但是,如果您想使用以前的代码,可以通过使用sql函数来分割字符串来实现。 linke下面:

Create function [dbo].[Split]
(
    @str nvarchar(4000), 
    @separator char(1)
)
returns table
AS
return (
    with tokens(p, a, b) AS (
        select 1, 1, charindex(@separator, @str)
        union all
        select p + 1, b + 1, charindex(@separator, @str, b + 1)
               from tokens
               where b > 0
    )
    select p-1 RowIndex,substring(@str, a, case when b > 0 then b-a ELSE 4000 end) AS s
           from tokens
  )

现在您可以编写如下代码:

using (SqlConnection con =new SqlConnection(/*Your Connection String*/))
        {
            using (SqlCommand cmd = new SqlCommand("SELECT * FROM Order_Header where Status IN (Select RowIndex from Split(@Values,','))"))
            {
                using (SqlDataAdapter sda = new SqlDataAdapter())
                {
                    try
                    {
                        cmd.Connection = con;
                        con.Open();
                        sda.SelectCommand = cmd;

                        // This is for test purposes
                        List<int> yourValues = new List<int>() { 1, 2, 3, 4, 5 };

                        //Get values for IN
                        string x = String.Join(",", yourValues.Select(s => String.Format("{0}", s)).ToArray());

                        // Add parameter
                        cmd.Parameters.AddWithValue("@Values", x);

                        DataTable dt = new DataTable();

                        sda.Fill(dt);
                        //order_details.SetDataSource(dt);
                        //SalesReport.ReportSource = order_details;
                    }
                    catch
                        (Exception
                            ex)
                    {
                        MessageBox.Show(ex.Message);
                    }
                    finally
                    {
                        con.Close();
                        sda.Dispose();
                        con.Dispose();
                    }
                }
            }

现在这也很好。