Многопараметрический поиск в SQL Server 2000 - PullRequest
1 голос
/ 11 февраля 2009

У меня есть экран поиска в приложении Visual Basic .Net, в котором есть текстовые поля для:

  1. Имя Варчар (50)
  2. Фамилия Варчар (50)
  3. Отчество Varchar (50)
  4. DOB DateTime
  5. Домашний телефон Varchar (10)
  6. Рабочий телефон Varchar (10)

Как мне создать хранимую процедуру в SQL Server 2000, которая позволила бы мне выполнять поиск по всем / некоторым / одному из полей. Если пользователь вводит данные только по имени, имени и номеру домашнего телефона, что мне нужно сделать для остальных параметров, где данные не были введены. Я попробовал оператор select ниже, но он не работает должным образом.

    Select Last_Name, First_Name, Mid_Name, DOB, Home_Phone, Work_Phone from dbo.tblClient
Where Last_Name Like '%@LastName' and
    First_Name Like '%@FirstName' and
    Mid_Name Like '%@MiddleName' and
    DOB Like '%DOB' and
    Home_Phone Like '%@HomePhone' and
    Work_Phone Like '%@WorkPhone'

Ответы [ 6 ]

3 голосов
/ 11 февраля 2009

Я часто использую этот шаблон:

</p> <pre><code>Select Last_Name, First_Name, Mid_Name, DOB, Home_Phone, Work_Phone from dbo.tblClient Where (@LastName is null or Last_Name Like '%'+ @LastName) and (@FirstName is null or First_Name Like '%'+ @FirstName) and (@HomePhone is null or Home_Phone Like '%'+ @HomePhone) -- etc...

Он будет игнорировать все, что не поставляется, но при этом даст хорошую производительность. Более того, он не прибегает к динамическому SQL, чтобы осуществить его.

0 голосов
/ 11 февраля 2009

Как насчет использования функции ISNULL () для определения, было ли значение передано в хранимую процедуру, и если нет, установки значения поля предложения WHERE для поиска равных себе в каждом случае (, если кто-то может подумать лучший выбор слов для описания этого, я обновлю ответ ).

 SELECT 
     Last_Name, 
     First_Name, 
     Mid_Name, 
     DOB, 
     Home_Phone, 
     Work_Phone 
 FROM 
     dbo.tblClient
 WHERE 
    Last_Name LIKE '%' + ISNULL(@LastName, Last_Name) AND
    First_Name LIKE '%' + ISNULL(@FirstName, First_Name) AND
    Mid_Name LIKE '%' ISNULL(@MiddleName, Mid_Name) AND
    DOB LIKE '%' + ISNULL(@DOB, DOB) AND
    Home_Phone LIKE '%' + ISNULL(@HomePhone, Home_Phone) AND
    Work_Phone LIKE '%' + ISNULL(@WorkPhone, Work_Phone) 

Вы также можете установить значение NULL по умолчанию для каждого из параметров хранимой процедуры.

0 голосов
/ 11 февраля 2009

Просто чтобы уточнить, почему ваш оригинальный SQL не работает;

Вам необходимо объединить подстановочный знак% со значением параметра, но вы создали буквальную строку, содержащую подстановочный знак и имя параметра, например,

Work_Phone Like '%@WorkPhone'

должно быть записано как

Work_Phone Like '%' + @WorkPhone

SQL, который у вас есть, должен работать, если вы возвращаете пустую строку для параметров, для которых не введено значение (т. Е. Вы возвращаете "", а не NULL) - сравнение Like для этих полей будет содержать только % подстановочный знак (то есть соответствует любому значению). Однако это не очень эффективно, так как в идеале вы хотите сравнивать только те поля, в которые пользователь ввел значение. Это, вероятно, потребует некоторого динамически генерируемого SQL, как показано в статье, на которую ссылается kenj.

Если ваша таблица tblClient не такая большая, то того, что вы сделали, может быть достаточно.

0 голосов
/ 11 февраля 2009

быстрое грязное решение.

Select Last_Name, First_Name, Mid_Name, DOB, Home_Phone, Work_Phone from dbo.tblClient
Where (Last_Name Like '%' + @LastName OR @LastName Is Null) and
(First_Name Like '%' + @FirstName OR @FirstName Is Null) and
(Mid_Name Like '%' + @MiddleName OR @MiddleName Is Null) and
(DOB Like '%' + @DOB OR @DOB Is Null) and
(Home_Phone Like '%' + @HomePhone OR @HomePhone Is Null and
(Work_Phone Like '%' + @WorkPhone OR @WorkPhone Is Null)

Примечание. Я исправил использование параметра. Не хотите ли вы также использовать подстановочный знак на другой стороне параметра? Также вы бы действительно использовали поле «Мне нравится дата рождения»?

Это не будет хорошо работать на большом столе. Гораздо более производительным решением было бы создание SQL только с обязательными полями в предложении Where.

0 голосов
/ 11 февраля 2009

В вашей хранимой процедуре или в вашем VB вам нужно будет решить, как вы хотите обрабатывать никакой ввод. Например я использую:

IF ltrim(rtrim(@FirstName)) = ''
SET @FirstName = null

... в моей хранимой процедуре. Возможно, вам придется экспериментировать с OR вместо AND. Вы в основном говорите своему запросу, что вы должны выполнить все эти условия, используя AND, независимо от того, нет ли ввода для ввода.

0 голосов
/ 11 февраля 2009

Быстрый способ сделать это будет что-то вроде

Где (Last_Name Like @LastName + '%' OR @LastName IS NULL) и (First_Name Like @FirstName + '%' ИЛИ ​​@FirstName IS NULL) и и т.д ...

Эрланд Соммарског имеет несколько замечательных статей о различных способах сделать это и их последствиях для производительности здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...