2013-05-30 5 views
0

Я пытаюсь сделать запрос, который делает следующее: у меня есть столбцы в моей базе данных Items, и эти столбцы называются Title, AuthorName и ItemType. Я хочу сделать следующее в моем запросе: Пользователь вводит имя_пользователя, заголовок и выбирает ItemType из выпадающего списка. Пользователь может оставить поля AuthorName или Title пустыми. Даже если он, например, не заполняет часть AuthorName, если элемент найден с указанным ItemType и указанный заголовок i показывает его в результатах. Аналогично, заголовок может быть пустым, в этом случае элемент с указанным именем пользователя указан в списке результатов. Вот мой запрос:Что не так в этом запросе в asp.net?

SELECT * 
FROM [Items] 
WHERE ((([Title] LIKE '%' + @Title + '%') 
      AND ([ItemType] = @ItemType) 
     ) 
      OR (([AuthorName] LIKE '%' + @AuthorName + '%') 
       AND ([ItemType] = @ItemType) 
      ) 
     ) 

Но если имя_илиииииииииииииидззззшшшшт, результатов не найдено. Может ли кто-нибудь помочь?

Благодаря

+0

Определить пустой. Пустой означает строку нулевой длины или нуль? –

+1

Просто имейте в виду, что ведущие подстановочные знаки, такие как%, препятствуют использованию базы данных любыми индексами, которые могут иметься в этом столбце, и заставляют ее выполнять сканирование таблицы. Трейлинг подстановочные знаки в порядке. Проблема в том, что только главные шаблоны. Если таблица большая, любой поиск, который вы делаете таким образом, будет медленным. Просто факт жизни. – criticalfix

ответ

2
Select ... 
From Items 
Where (@Title Is Null Or Title Like '%' + @Title + '%') 
    And (@AuthorName Is Null Or AuthorName Like '%' + @AuthorName + '%') 
    And ItemType = @ItemType 

В ASP.NET, вы должны проверять ваши значения формы против string.IsNullOrEmpty и если оно истинно, посылая DBNull.Value вашего параметризованного запроса вместо пустой строки.

Если вы настаиваете на пропускании пустую строку для параметров (что не является предпочтительным), то запрос должен проверить для пустых строк:

Select ... 
From Items 
Where (Len(@Title) = 0 Or Title Like '%' + @Title + '%') 
    And (Len(@AuthorName) = 0 Or AuthorName Like '%' + @AuthorName + '%') 
    And ItemType = @ItemType 

В SQL Server, функция Len будет игнорировать пробелы. Если вы действительно хотите, чтобы сходить с ума и делать всю свою проверку в запросе (что опять-таки не рекомендуется), то вы хотели бы объяснить ваши параметры быть пустые строки, все пробелы или аннулирует:

Select ... 
From Items 
Where (Len(Coalesce(@Title,'')) = 0 Or Title Like '%' + @Title + '%') 
    And (Len(Coalesce(@AuthorName,'')) = 0 Or AuthorName Like '%' + @AuthorName + '%') 
    And ItemType = @ItemType 
1

Попробуйте что-нибудь как это:

SELECT * 
FROM [Items] 
WHERE ([ItemType] = @ItemType) 
     AND ([Title] LIKE '%' + @Title + '%' OR @Title IS NULL) 
     AND ([AuthorName] LIKE '%' + @AuthorName + '%' OR @AuthorName IS NULL) 

Просто убедитесь, что пройти в NULL значений (System.DBNull.Value) при AuthorName или Title пуст.

UPDATE:

Предполагая AuthorName и Title передаются в код-за как пустые строки, когда они «не выбрано», вы можете сделать что-то вроде этого (где authorName и title являются строки, передаваемые в ваш код-сзади):

VB:

cmd.Parameters.Add("AuthorName", SqlDbType.VarChar, 50).Value = IIf(authorName.length > 0, authorName, System.DBNull.Value) 
cmd.Parameters.Add("Title", SqlDbType.VarChar, 50).Value = IIf(title.length > 0, title, System.DBNull.Value) 

C#:

cmd.Parameters.Add("AuthorName", SqlDbType.VarChar, 50).Value = (authorName.length > 0 ? authorName : System.DBNull.Value); 
cmd.Parameters.Add("Title", SqlDbType.VarChar, 50).Value = (title.length > 0 ? title : System.DBNull.Value); 
+0

Это не сработало, я не уверен, как обязательно передавать значения NULL (System.DBNull.Value), когда AuthorName или Title пуст. Это может быть проблема? Как я могу передать значения NULL? – yrazlik

+0

@bigO: см. Обновленный ответ. – pete

1

Я написал целый учебник по этому вопросу в своем блоге кода по адресу code.scottshipp.com. Доступна полная загрузка кода в этом учебнике. Он показывает, как настроить его как хранимую процедуру, а также подробно описывает, как построить предложение where в вашем запросе. Таким образом, он охватывает оба экземпляра. Вам может быть проще пройти маршрут Хранимые процедуры, так что вы можете дать ему прочитать.

Следует иметь в виду, что для этого существуют различные методы, но есть и некоторые «gotcha», которые заставят ваш код работать в некоторых ситуациях, а не другие, если вы используете что-то вроде функции ISNULL.

Вместо этого, в общем, я бы рекомендовал следующее:

Добавьте следующий фрагмент кода в любой части, где положение вы ожидаете иногда быть пустым:

OR SomeParam IS NULL 

Кроме того, это хорошо для читаемость по всем скобкам. Сделайте это для каждого параметра, который, по вашему мнению, может в какой-то момент быть пустым. Это означает, например, что ваш оператор выбора будет:

SELECT * 
FROM [Items] 
WHERE ((([Title] LIKE '%' + @Title + '%' OR [Title] IS NULL) 
     AND ([ItemType] = @ItemType OR [ItemType] IS NULL) 
    ) 
     OR (([AuthorName] LIKE '%' + @AuthorName + '%' OR [AuthorName] IS NULL) 
      AND ([ItemType] = @ItemType OR [ItemType] IS NULL) 
     ) 
    ) 
1

Пожалуйста, попробуйте это

SELECT * 
FROM [Items] 
WHERE ((([Title] LIKE CASE WHEN ISNULL(@Title,'')='' THEN [Title] ELSE '%' + @Title + '%' END) 
      AND ([ItemType] = @ItemType) 
     ) 
      OR (([AuthorName] LIKE CASE ISNULL(@AuthorName,'')='' THEN [AuthorName] ELSE '%' + @AuthorName + '%' END) 
       AND ([ItemType] = @ItemType) 
      ) 
     ) 

Это поможет. Это будет работать даже в том случае, если вы не пропустите Title или Authorname.

+0

Спасибо, но он дает ошибку, говоря, что выражение небулевого типа указано в контексте, где ожидается условие, рядом с «THEN». – yrazlik

+0

Попробуйте еще раз У меня есть запрос на обновление в моем сообщении ... –