【问题标题】:Conversion failed when converting the nvarchar value .. to data type int将 nvarchar 值 .. 转换为数据类型 int 时转换失败
【发布时间】:2016-02-02 02:54:51
【问题描述】:

我正在尝试执行以下查询,但遇到异常。

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 值 ''1','2','3','4','5'' 转换为数据类型 int 时转换失败。

为什么会这样?请帮忙

【问题讨论】:

  • String.Format("{0}", s)。无论如何,您应该将多个参数作为 TVP 传递,并且不要构建自定义 sql
  • @lad2025 我也试过了。我得到了同样的例外。
  • 除非@parameter 是表值参数,否则您不能执行IN (@parameter)。您正在传递 1 个值,一个字符串,其中包含单个字符串值 "'1', '2', '3', '4', '5'"。这行不通。
  • @LasseV.Karlsen 我还有其他方法吗?
  • 糟糕的副本,因为它会生成一个表扫描。有更好的方法,使用表值参数,或者生成正确的 SQL。我现在找不到可以链接的好副本,其他人可能会有更好的运气。

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


【解决方案1】:

您的状态是 varchar,您的列表是 int。 如果它包含如下数据,则需要将您的状态转换为 int:- select cast(status as int) from (select '1' as status)x;

【讨论】:

  • Status 是 int,我尝试更改以下语句: string x = String.Join(",", yourValues.Select(s => String.Format("{0}", s)) .ToArray());
  • @user1377504 或尝试使用 CAST(@Values AS int)
  • 这是一串值,而不是单个值。我不确定转换为 INT 是否可行
  • @user1377504 但是您可以尝试理想情况下,查询应该形成为 SELECT * FROM Order_Header where Status IN ('1','2','3','4','5' ) 但状态是 int,因此您需要将这些数字列表转换为 int 才能使您的查询正常工作。
【解决方案2】:

更新

我已将您的代码更改如下,现在可以正常工作了:

方法一:

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();
                    }
                }
            }

方法二:

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

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();
                    }
                }
            }

现在这也可以正常工作了。

【讨论】:

  • 我试过了,但它给了我同样的例外。
猜你喜欢
  • 2020-04-17
  • 2011-08-29
  • 2015-06-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多