2013-12-05 7 views
0

Я пытаюсь создать функцию поиска, которая использует TextBox и два DropDownLists для возврата записей из моей базы данных MSSQL. Способ, которым я настроен, - это передать поисковые запросы через QueryStrings в GridView на отдельной странице. Вот что у меня есть для функции поиска:Ошибка конверсии при преобразовании значения varchar '[]' в тип данных int


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.

Я новичок в этом, так извиняюсь, если это что-то глупое, и я старался как можно раньше до публикации, но я просто не могу пройти мимо этого.

Заранее спасибо.

+1

Какой тип поля Product_Rental и что в нем находится? Какой тип переменной @Product_Rental, и что в ней? Это сообщение об ошибке сообщает вам, что значение varchar, которое является проблематичным, имеет две квадратные фигурные скобки и аббревиатуру '', например, ''. Это говорит вам, что все между этими отметками находится в ценности, которую он не может преобразовать. Проверьте свои входы. Похоже, у вас есть значение метки «cue» как фактический текст на входе, и вы отправляете это, не проверяя, действительно ли оно. –

+0

Поле Product_Rental является VARCHAR, а переменная @Product_Rental является строкой. Их содержание - это цены, поэтому они могут иметь до двух знаков после запятой. К сожалению, я помещаю [] в сообщение об ошибке в качестве примера. – jimmyahughes

+0

Что-то не похоже на то, что SQL лает, что это INT, но независимо, если Product_Rental - это цены, тогда я бы рекомендовал, чтобы ваш тип SQL DB был FLOAT, DECIMAL или MONEY. – N0Alias

ответ

2

Проблема здесь:.

Product_Rental BETWEEN @Product_Rental AND @Product_Rental + 50 

Поскольку вы используете + 50data type precedence пинки в Документах состояние:

When an operator combines two expressions of different data types, the rules for data type precedence specify that the data type with the lower precedence is converted to the data type with the higher precedence. If the conversion is not a supported implicit conversion, an error is returned. When both operand expressions have the same data type, the result of the operation has that data type.

Так внутри SQL Server пытается преобразовать @Product_Rental к междунар (потому что 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 преобразует к междунар, но если он имеет десятичную точку он не будет, как можно показать с помощью:

SELECT CONVERT(INT, '50.0'); 

Я хотел бы предложить, если ваш столбец Product_Rental содержит десятичные данные, то он должен быть десятичного типа, как и любые параметры, используемые для фильтрации столбца.

+0

Спасибо. Это очень информативно. Я изменил тип столбца Product_Rental, как вы предложили. – jimmyahughes

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) 
+0

Спасибо за ваш ответ. Хорошо, это имеет смысл, но я не уверен, где происходит конвертация в INT. В столбце базы данных находится VARCHAR, а параметры SQL, которые я использую, - это все типы String. – jimmyahughes

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]', которое в любом случае не может быть преобразовано в float.

+1

Хотя ваш ответ в основном прав в том, что происходит неверное преобразование, понятие, что * «BETWEEN будет пытаться неявно преобразовывать операнды varchar в int» *, не означает, что преобразование не имеет ничего общего с оператором «BETWEEN», оно должно для объединения разных типов данных в одном выражении. – GarethD

+0

Спасибо! Работал шармом. Извинения за [] в ошибке SQL. – jimmyahughes

+0

@GarethD Спасибо –

Смежные вопросы