Поиск в базе данных с несколькими вариантами - PullRequest
0 голосов
/ 16 июля 2011

Я использую SQL Server 2008 Express с расширенными службами. У меня есть вид:

IF EXISTS (select * from sys.views where object_id = object_id(N'[dbo].[vw_PersonDetails]'))
    DROP VIEW vw_PersonDetails
GO

CREATE VIEW vw_PersonDetails
AS
    SELECT
        p.PersonID, p.Title, 
        p.FirstName, p.LastName,
        a.AddressLine1, a.AddressLine2, a.AddressLine3, a.AddressLine4,
        a.Country, a.PostalCode, 
        a.PhoneNumber, a.Email, p.EntryDate
    FROM  
        [dbo].[Persons] p
    INNER JOIN 
        [dbo].[Address] a ON p.PersonID = a.PersonID
GO

Теперь я должен искать это представление с каждым из столбцов в качестве параметров.

Ex:

IF (@firstName != NULL OR @firstName != '') AND 
   (@lastName != NULL OR @lastName != '') AND 
   (@addressLine1 != NULL OR @addressLine1 != '') AND 
   (@postalCode != NULL OR @postalCode != '') AND 
   (@country != NULL OR @country != '') AND
   (@phoneNumber != NULL OR @phoneNumber != '') AND 
   (@email != NULL OR @email != '') AND 
   (@entryDate != NULL)
BEGIN
    SELECT * 
    FROM dbo.vw_PersonDetails 
    WHERE 
        (FirstName LIKE [dbo].[GetSearchString](@firstName) OR
        LastName LIKE [dbo].[GetSearchString](@lastName) OR
        AddressLine1 LIKE [dbo].[GetSearchString](@addressLine1) OR
        Country LIKE [dbo].[GetSearchString](@country) OR
        PostalCode LIKE [dbo].[GetSearchString](@postalCode) OR
        PhoneNumber LIKE [dbo].[GetSearchString](@phoneNumber) OR
        Email LIKE [dbo].[GetSearchString](@email) OR
        EntryDate = @entryDate
       )
END

Теперь есть другие варианты, кроме записи бесконечного трейла IF-ELSE-IF в хранимой процедуре или динамического построения запроса. Пожалуйста, помогите.

Другой вопрос заключается в том, что будет лучше: написание такой хранимой процедуры или выполнение динамического запроса из кода.

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

Ответы [ 2 ]

1 голос
/ 16 июля 2011

Вы можете сделать это одним простым запросом:

SELECT * from dbo.vw_PersonDetails WHERE (
    (@firstName IS NULL OR @firstName = '' OR FirstName like @firstName) AND
    ... (same thing for other parameters)

Это будет работать из-за того, что SQL Server достаточно интеллектуален, чтобы замкнуть оценку ожидаемым образом.Однако это на самом деле не гарантируется спецификацией.

Если вы хотите быть в безопасности, вы можете форсировать порядок оценки, выполнив следующее:

SELECT * from dbo.vw_personDetails WHERE (
    (CASE 
        WHEN @firstname IS NULL THEN 1
        WHEN @firstname='' THEN 1
        WHEN FirstName like @firstName THEN 1
        ELSE 0
     END=1) AND
    .... (same thing for other parameters)
1 голос
/ 16 июля 2011

Вам нужно заполнить всю строку SearchString для выполнения запроса (из-за условия AND в вашем операторе IF).

Вы можете создать динамический запрос для запуска независимо от того, переданы параметры или нет:

DECLARE @sqlCommand VARCHAR(MAX)
SELECT @sqlCommand = 'SELECT * FROM dbo.vw_PersonDetails WHERE 1=1'

IF  (@firstName != NULL OR @firstName != '') SELECT @sqlCommand = @sqlCommand + ' AND FirstName LIKE [dbo].[GetSearchString](@firstName)'
IF  (@lastName != NULL OR @lastName != '') SELECT @sqlCommand = @sqlCommand + ' AND LastName LIKE [dbo].[GetSearchString](@lastName)'
IF  (@addressLine1 != NULL OR @addressLine1 != '') SELECT @sqlCommand = @sqlCommand + ' AND AddressLine1 LIKE [dbo].[GetSearchString](@addressLine1)'

.....

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