转换varchar值时转换失败' []'到数据类型int

时间:2013-12-05 14:09:02

标签: asp.net sql sql-server vb.net search

我试图创建一个使用TextBox和两个DropDownLists从我的MSSQL DB返回条目的搜索功能。我设置它的方法是通过QueryStrings将搜索查询传递到单独页面上的GridView。这就是我对搜索功能所拥有的:


Partial Class Includes_LeftCol
  Inherits System.Web.UI.UserControl

  Public Sub btnSearch_Click(sender As Object, e As System.EventArgs) Handles btnSearch.Click

    Dim SelectURLRangePrice As String

    If tbxSearch.Text.Length = 0 And ddlRangeName.SelectedValue = "" And ddlPriceRange.SelectedValue = "" Then

      SelectURLRangePrice = "SearchResults.aspx"
      Response.Redirect(SelectURLRangePrice)

    ElseIf tbxSearch.Text.Length = 0 And ddlRangeName.SelectedValue = "" And ddlPriceRange.SelectedValue.Length > 0 Then

      SelectURLRangePrice = "SearchResults.aspx?price=" & ddlPriceRange.Text
      Response.Redirect(SelectURLRangePrice)

    ElseIf tbxSearch.Text.Length = 0 And ddlRangeName.SelectedValue.Length > 0 And ddlPriceRange.SelectedValue.Length > 0 Then

      SelectURLRangePrice = "SearchResults.aspx?range=" & ddlRangeName.Text & "&price=" & ddlPriceRange.Text
      Response.Redirect(SelectURLRangePrice)

    End If

    Dim SelectURLRange As String

    If tbxSearch.Text.Length = 0 And ddlRangeName.SelectedValue.Length = 0 Then

      SelectURLRange = "SearchResults.aspx"
      Response.Redirect(SelectURLRange)

    ElseIf tbxSearch.Text.Length = 0 And ddlRangeName.SelectedValue.Length > 0 Then

      SelectURLRange = "SearchResults.aspx?range=" & ddlRangeName.Text
      Response.Redirect(SelectURLRange)

    End If

    Dim SelectURL As String

    If tbxSearch.Text.Length = 0 Then

      SelectURL = "SearchResults.aspx"
      Response.Redirect(SelectURL)

    ElseIf tbxSearch.Text.Length > 0 Then

      SelectURL = "SearchResults.aspx?search=" & tbxSearch.Text
      Response.Redirect(SelectURL)

    End If

  End Sub

End Class

这是我的SQL声明:



    SELECT        Product_Rental, Product_ID, Range_Name, Model_Name, Product_Name, Product_Year, Product_Code, Product_Active, Product_DateAdded
    FROM            Products
    WHERE        (Range_Name LIKE '%' + @Range_Name + '%') OR
                             (Model_Name LIKE '%' + @Model_Name + '%') OR
                             (Product_Name LIKE '%' + @Product_Name + '%') OR
                             (Product_Code LIKE '%' + @Product_Code + '%') OR
                             (Product_Year LIKE '%' + @Product_Year + '%') OR
                             (Product_Rental BETWEEN @Product_Rental AND @Product_Rental + 50)


提交后,我收到以下错误:

转换varchar值时转换失败' [例如209.35]'数据类型为int。

我是初学者,如果这是一件愚蠢的话,我会道歉,并且在发布之前我已尽力尽力,但我无法通过这个

提前致谢。

3 个答案:

答案 0 :(得分:2)

问题在于:

Product_Rental BETWEEN @Product_Rental AND @Product_Rental + 50

因为您正在使用+ 50 data type precedence,所以文档声明:

  

当运算符组合了两种不同数据类型的表达式时,数据类型优先级的规则指定具有较低优先级的数据类型转换为具有较高优先级的数据类型。如果转换不是受支持的隐式转换,则会返回错误。当两个操作数表达式具有相同的数据类型时,操作的结果具有该数据类型。

因此,内部SQL Server尝试将@Product_Rental转换为int(因为50是int,而int的优先级高于varchar)。所以每当这可以简单地再现:

DECLARE @Var VARCHAR(6) = '50';
SELECT   *
FROM    (VALUES (1)) T (A)
WHERE   A < @Var + 50;

然后检查执行计划XML,我们可以看到幕后的comversion:

<ScalarOperator ScalarString="(1)&lt;(CONVERT_IMPLICIT(int,[@Var],0)+(50))">

这基本上表明SQL Server已基本转向

A < @Var + 50

进入

A < CONVERT(INT, @Var) + 50;

如果@Var转换为int,这很好,但是如果它有小数点则不会,如下所示:

SELECT  CONVERT(INT, '50.0');

我建议如果您的列Product_Rental包含十进制数据,那么它应该是十进制类型,就像用于过滤列的任何参数一样。

答案 1 :(得分:0)

SQL Type INT用于整数(1,2,3)。 FLOAT可以支持小数。像[和]这样的文本字符肯定不适用于INT列。

从评论中编辑:

由于Product_Rental字段是VarChar,请尝试更改为此(如果您不想更改表格上的类型,我建议):

--Make @Product_Rental a numeric type first.
 (CAST(Product_Rental AS FLOAT) BETWEEN @Product_Rental AND @Product_Rental + 50)

答案 2 :(得分:0)

问题在于:

Product_Rental BETWEEN @Product_Rental AND @Product_Rental + 50

你有多种类型的操作数。其中一个是整数。 SQL Server正在尝试将所有内容转换为整数,因此它们都可以进行有意义的比较,苹果到苹果(为什么它会选择整数?优先级规则)。在这种情况下,它无法做到这一点,因为在SQL中,您无法将带小数点的varchar隐式转换为整数。信息将在那里丢失,因此它不会自动为您执行此操作。 如果你真的想要所有整数,你必须转换为float,然后隐式地将float截断为整数。更好的方法是将此处的所有内容转换为浮动前端,因为您确实希望在此处比较浮点数。如果你这样做,SQL Server就不会在猜测你想要什么样的数据类型。

因此,如果varchar值具有小数点,您将得到类似于您给我们的错误,但它不会有方括号。 (请不要在错误消息中插入随机字符,并告诉人们SQL Server给你的是什么,如果不是这样的话)。

试试这个:

convert(float,Product_Rental) 
  BETWEEN convert(float,@Product_Rental) 
      AND convert(float,@Product_Rental) + 50

这就是为什么你应该在表和变量中使用正确的数据类型。两者都应该是十进制或一直浮动。

如果变量或其中任何一个字段中的实际值为'[e.g. 209.35]',则无论如何都无法将其转换为浮点数。