0

SQL Server 2008 R2 데이터베이스에서 1 - 3 개 필드의 하위 문자열에 대한 전체 텍스트 검색을 수행해야합니다. 비어 있지 않은 검색어가있는 필드 만 검색해야합니다. Entity Framework를 사용하며 검색은 더 큰 LINQ 쿼리의 일부이므로 테이블 값 함수로 구성 할 수 있어야합니다. 따라서 동적 SQL을 사용할 수 없습니다. 지금까지 나는 다음과 같은 UDF와 함께 올라와있다 : 검색을 완료하는 데 10 초 복용 매우 차선 쿼리 계획과 검색에 인도에서UDF 내 쿼리에서 WHERE 절의 일부 제외

CREATE FUNCTION [dbo].[SearchPublications] 
(
@version int, 
@comment nvarchar(4000), 
@description nvarchar(4000), 
@tags nvarchar(4000) 
) 
RETURNS 
@Table_Var TABLE 
(
[ID] [int] NOT NULL, 
[IDPublicationType] [int] NOT NULL, 
[IDCover] [int] NULL, 
[IDSmallCover] [int] NULL, 
[IDContent] [int] NOT NULL, 
[Cost] [decimal](10, 2) NOT NULL, 
[Language] [smallint] NOT NULL, 
[Flags] [tinyint] NOT NULL, 
[Year] [smallint] NOT NULL, 
[Guid] [nvarchar](255) NOT NULL, 
[Key] [nvarchar](25) NOT NULL, 
[CTime] [datetime] NOT NULL 
) 
AS 
BEGIN 
declare @commentParam nvarchar(4000), @descriptionParam nvarchar(4000), @tagsParam nvarchar(4000), @guid nvarchar(32) = 'E442FB8EA8624E289BD13753480AFA8B' 
select @commentParam = isnull('"' + @comment + '*"', @guid) 
select @descriptionParam = isnull('"' + @description + '*"', @guid) 
select @tagsParam = isnull('"' + @tags + '*"', @guid) 

insert @Table_Var 
select * 
from Publications 
where (@commentParam = @guid or exists (select 
1 from PublicationFields 
where IDPublication = Publications.ID and IDField = 3 and IDVersion = @version and 
contains(LongValue, @commentParam) 
)) 
and (@descriptionParam = @guid or exists (select 
1 from PublicationFields 
where IDPublication = Publications.ID and IDField = 4 and IDVersion = @version and 
contains(LongValue, @descriptionParam) 
)) 
and (@tagsParam = @guid or exists (select 
1 from PublicationFields 
where IDPublication = Publications.ID and IDField = 5 and IDVersion = @version and 
contains(LongValue, @tagsParam)) 
) 
RETURN 
END 

그러나 @param = @guid or... 구조의 사용은 빈 매개 변수를 제외 할 수 있습니다. 상기 구문없이 수행 된 동일한 검색은 거의 즉시 반환되지만,이 경우에는 다양한 수의 검색어를 사용할 수 없습니다. 동적 SQL이 불가능할 때 쿼리에서 WHERE 절의 일부를 제외시키는 더 좋은 방법이 있습니까? 3 개의 검색 매개 변수의 각 조합에 대해 별도의 TVF를 작성하는 것은 피하고 싶습니다.

답변

0

내 자신의 질문에 대답 :이 솔루션은 단지 지정된 하나의 필드

CREATE FUNCTION [dbo].[SearchPublications] 
( 
    @version int, 
    @field int, 
    @search nvarchar(4000) 
) 
RETURNS TABLE 
AS 
RETURN 
(
    select Publications.* 
    from Publications, PublicationFields 
    where IDPublication = Publications.ID and IDField = @field and IDVersion = @version and 
    contains(LongValue, @search) 
) 

후 교차 방법을 사용하여 LINQ 쿼리에 필요에 따라에 많은 통화를 결합하여 검색하는 함수를 작성했다 :

if (query == null) 
{ 
    query = provider.SearchPublications(search.IDVersion, id, string.Format("\"{0}*\"", value)); 
} 
else 
{ 
    query = query.Intersect(provider.SearchPublications(search.IDVersion, id, string.Format("\"{0}*\"", value))); 
}